--- linux-source-2.6.22-2.6.22.orig/scripts/kconfig/conf.c +++ linux-source-2.6.22-2.6.22/scripts/kconfig/conf.c @@ -64,7 +64,7 @@ } } -static void conf_askvalue(struct symbol *sym, const char *def) +static int conf_askvalue(struct symbol *sym, const char *def) { enum symbol_type type = sym_get_type(sym); tristate val; @@ -79,7 +79,7 @@ printf("%s\n", def); line[0] = '\n'; line[1] = 0; - return; + return 0; } switch (input_mode) { @@ -89,23 +89,23 @@ case set_random: if (sym_has_value(sym)) { printf("%s\n", def); - return; + return 0; } break; case ask_new: case ask_silent: if (sym_has_value(sym)) { printf("%s\n", def); - return; + return 0; } check_stdin(); case ask_all: fflush(stdout); fgets(line, 128, stdin); - return; + return 1; case set_default: printf("%s\n", def); - return; + return 1; default: break; } @@ -115,7 +115,7 @@ case S_HEX: case S_STRING: printf("%s\n", def); - return; + return 1; default: ; } @@ -166,6 +166,7 @@ break; } printf("%s", line); + return 1; } int conf_string(struct menu *menu) @@ -179,7 +180,8 @@ def = sym_get_string_value(sym); if (sym_get_string_value(sym)) printf("[%s] ", def); - conf_askvalue(sym, def); + if (!conf_askvalue(sym, def)) + return 0; switch (line[0]) { case '\n': break; @@ -236,7 +238,8 @@ if (sym->help) printf("/?"); printf("] "); - conf_askvalue(sym, sym_get_string_value(sym)); + if (!conf_askvalue(sym, sym_get_string_value(sym))) + return 0; strip(line); switch (line[0]) { --- linux-source-2.6.22-2.6.22.orig/MAINTAINERS +++ linux-source-2.6.22-2.6.22/MAINTAINERS @@ -3593,6 +3593,15 @@ W: http://www.kernel.dk S: Maintained +UNIONFS +P: Erez Zadok +M: ezk@cs.sunysb.edu +P: Josef "Jeff" Sipek +M: jsipek@cs.sunysb.edu +L: unionfs@filesystems.org +W: http://unionfs.filesystems.org +S: Maintained + USB ACM DRIVER P: Oliver Neukum M: oliver@neukum.name --- linux-source-2.6.22-2.6.22.orig/Makefile +++ linux-source-2.6.22-2.6.22/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 22 -EXTRAVERSION = +EXTRAVERSION = .9 NAME = Holy Dancing Manatees, Batman! # *DOCUMENTATION* --- linux-source-2.6.22-2.6.22.orig/init/initramfs.c +++ linux-source-2.6.22-2.6.22/init/initramfs.c @@ -541,6 +541,26 @@ #endif +/* Tries to read the initramfs if it's already there, for ACPI Table Overiding */ +void __init early_populate_rootfs(void) +{ + char *err = unpack_to_rootfs(__initramfs_start, + __initramfs_end - __initramfs_start, 0); + if (err) + return; +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + printk(KERN_INFO "Early unpacking initramfs..."); + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 0); + if (err) + return; + printk(" done\n"); + } +#endif + return; +} + static int __init populate_rootfs(void) { char *err = unpack_to_rootfs(__initramfs_start, --- linux-source-2.6.22-2.6.22.orig/init/main.c +++ linux-source-2.6.22-2.6.22/init/main.c @@ -97,8 +97,10 @@ extern void free_initmem(void); #ifdef CONFIG_ACPI extern void acpi_early_init(void); +extern void early_populate_rootfs(void); #else static inline void acpi_early_init(void) { } +static inline void early_populate_rootfs(void) { } #endif #ifndef CONFIG_DEBUG_RODATA static inline void mark_rodata_ro(void) { } @@ -630,6 +632,7 @@ check_bugs(); + early_populate_rootfs(); /* For DSDT override from initramfs */ acpi_early_init(); /* before LAPIC and SMP init */ /* Do the rest non-__init'ed, we're now alive */ --- linux-source-2.6.22-2.6.22.orig/init/version.c +++ linux-source-2.6.22-2.6.22/init/version.c @@ -36,7 +36,11 @@ /* FIXED STRINGS! Don't touch! */ const char linux_banner[] = "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION +#ifdef CONFIG_VERSION_SIGNATURE + " (" CONFIG_VERSION_SIGNATURE ")" +#endif + "\n"; const char linux_proc_banner[] = "%s version %s" --- linux-source-2.6.22-2.6.22.orig/init/Kconfig +++ linux-source-2.6.22-2.6.22/init/Kconfig @@ -95,6 +95,15 @@ which is done within the script "scripts/setlocalversion".) +config VERSION_SIGNATURE + string "Arbitrary version signature" + help + This string will be created in a file, /proc/version_signature. It + is useful in determining arbitrary data about your kernel. For instance, + if you have several kernels of the same version, but need to keep track + of a revision of the same kernel, but not affect it's ability to load + compatible modules, this is the easiest way to do that. + config SWAP bool "Support for paging of anonymous memory (swap)" depends on MMU && BLOCK @@ -505,6 +514,7 @@ config TIMERFD bool "Enable timerfd() system call" if EMBEDDED depends on ANON_INODES + depends on BROKEN default y help Enable the timerfd() system call that allows to receive timer --- linux-source-2.6.22-2.6.22.orig/mm/filemap_xip.c +++ linux-source-2.6.22-2.6.22/mm/filemap_xip.c @@ -406,7 +406,7 @@ if (count == 0) goto out_backing; - ret = remove_suid(filp->f_path.dentry); + ret = remove_suid(&filp->f_path); if (ret) goto out_backing; --- linux-source-2.6.22-2.6.22.orig/mm/hugetlb.c +++ linux-source-2.6.22-2.6.22/mm/hugetlb.c @@ -101,13 +101,20 @@ static int alloc_fresh_huge_page(void) { - static int nid = 0; + static int prev_nid; struct page *page; - page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN, - HUGETLB_PAGE_ORDER); - nid = next_node(nid, node_online_map); + static DEFINE_SPINLOCK(nid_lock); + int nid; + + spin_lock(&nid_lock); + nid = next_node(prev_nid, node_online_map); if (nid == MAX_NUMNODES) nid = first_node(node_online_map); + prev_nid = nid; + spin_unlock(&nid_lock); + + page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN, + HUGETLB_PAGE_ORDER); if (page) { set_compound_page_dtor(page, free_huge_page); spin_lock(&hugetlb_lock); --- linux-source-2.6.22-2.6.22.orig/mm/filemap.c +++ linux-source-2.6.22-2.6.22/mm/filemap.c @@ -1905,20 +1905,20 @@ } EXPORT_SYMBOL(should_remove_suid); -int __remove_suid(struct dentry *dentry, int kill) +int __remove_suid(struct path *path, int kill) { struct iattr newattrs; newattrs.ia_valid = ATTR_FORCE | kill; - return notify_change(dentry, &newattrs); + return notify_change(path->dentry, path->mnt, &newattrs); } -int remove_suid(struct dentry *dentry) +int remove_suid(struct path *path) { - int kill = should_remove_suid(dentry); + int kill = should_remove_suid(path->dentry); if (unlikely(kill)) - return __remove_suid(dentry, kill); + return __remove_suid(path, kill); return 0; } @@ -2146,22 +2146,9 @@ } status = a_ops->prepare_write(file, page, offset, offset+bytes); - if (unlikely(status)) { - loff_t isize = i_size_read(inode); + if (unlikely(status)) + goto fs_write_aop_error; - if (status != AOP_TRUNCATED_PAGE) - unlock_page(page); - page_cache_release(page); - if (status == AOP_TRUNCATED_PAGE) - continue; - /* - * prepare_write() may have instantiated a few blocks - * outside i_size. Trim these off again. - */ - if (pos + bytes > isize) - vmtruncate(inode, isize); - break; - } if (likely(nr_segs == 1)) copied = filemap_copy_from_user(page, offset, buf, bytes); @@ -2170,41 +2157,54 @@ cur_iov, iov_base, bytes); flush_dcache_page(page); status = a_ops->commit_write(file, page, offset, offset+bytes); - if (status == AOP_TRUNCATED_PAGE) { - page_cache_release(page); - continue; + if (unlikely(status < 0 || status == AOP_TRUNCATED_PAGE)) + goto fs_write_aop_error; + if (unlikely(copied != bytes)) { + status = -EFAULT; + goto fs_write_aop_error; } zero_length_segment: - if (likely(copied >= 0)) { - if (!status) - status = copied; + if (unlikely(status > 0)) /* filesystem did partial write */ + copied = status; - if (status >= 0) { - written += status; - count -= status; - pos += status; - buf += status; - if (unlikely(nr_segs > 1)) { - filemap_set_next_iovec(&cur_iov, - &iov_base, status); - if (count) - buf = cur_iov->iov_base + - iov_base; - } else { - iov_base += status; - } + if (likely(copied >= 0)) { + written += copied; + count -= copied; + pos += copied; + buf += copied; + if (unlikely(nr_segs > 1)) { + filemap_set_next_iovec(&cur_iov, + &iov_base, copied); + if (count) + buf = cur_iov->iov_base + iov_base; + } else { + iov_base += copied; } } - if (unlikely(copied != bytes)) - if (status >= 0) - status = -EFAULT; unlock_page(page); mark_page_accessed(page); page_cache_release(page); - if (status < 0) - break; balance_dirty_pages_ratelimited(mapping); cond_resched(); + continue; + +fs_write_aop_error: + if (status != AOP_TRUNCATED_PAGE) + unlock_page(page); + page_cache_release(page); + + /* + * prepare_write() may have instantiated a few blocks + * outside i_size. Trim these off again. Don't need + * i_size_read because we hold i_mutex. + */ + if (pos + bytes > inode->i_size) + vmtruncate(inode, inode->i_size); + if (status == AOP_TRUNCATED_PAGE) + continue; + else + break; + } while (count); *ppos = pos; @@ -2269,7 +2269,7 @@ if (count == 0) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; --- linux-source-2.6.22-2.6.22.orig/mm/mmap.c +++ linux-source-2.6.22-2.6.22/mm/mmap.c @@ -2157,7 +2157,7 @@ vma->vm_start = addr; vma->vm_end = addr + len; - vma->vm_flags = vm_flags | mm->def_flags; + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &special_mapping_vmops; --- linux-source-2.6.22-2.6.22.orig/mm/shmem.c +++ linux-source-2.6.22-2.6.22/mm/shmem.c @@ -1051,7 +1051,7 @@ pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); pvma.vm_pgoff = idx; pvma.vm_end = PAGE_SIZE; - page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0); + page = alloc_page_vma(gfp, &pvma, 0); mpol_free(pvma.vm_policy); return page; } @@ -1071,7 +1071,7 @@ static inline struct page * shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx) { - return alloc_page(gfp | __GFP_ZERO); + return alloc_page(gfp); } #endif @@ -1280,6 +1280,7 @@ info->alloced++; spin_unlock(&info->lock); + clear_highpage(filepage); flush_dcache_page(filepage); SetPageUptodate(filepage); } @@ -1518,7 +1519,7 @@ if (err || !count) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; --- linux-source-2.6.22-2.6.22.orig/mm/mlock.c +++ linux-source-2.6.22-2.6.22/mm/mlock.c @@ -244,9 +244,12 @@ locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + if (lock_limit == RLIM_INFINITY) + allowed = 1; lock_limit >>= PAGE_SHIFT; spin_lock(&shmlock_user_lock); - if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK)) + if (!allowed && + locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK)) goto out; get_uid(user); user->locked_shm += locked; --- linux-source-2.6.22-2.6.22.orig/mm/tiny-shmem.c +++ linux-source-2.6.22-2.6.22/mm/tiny-shmem.c @@ -86,7 +86,7 @@ file->f_mode = FMODE_WRITE | FMODE_READ; /* notify everyone as to the change of file size */ - error = do_truncate(dentry, size, 0, file); + error = do_truncate(dentry, file->f_path.mnt, size, 0, file); if (error < 0) goto close_file; --- linux-source-2.6.22-2.6.22.orig/mm/vmalloc.c +++ linux-source-2.6.22-2.6.22/mm/vmalloc.c @@ -578,9 +578,9 @@ } #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) -#define GFP_VMALLOC32 GFP_DMA32 +#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA) -#define GFP_VMALLOC32 GFP_DMA +#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL #else #define GFP_VMALLOC32 GFP_KERNEL #endif --- linux-source-2.6.22-2.6.22.orig/mm/readahead.c +++ linux-source-2.6.22-2.6.22/mm/readahead.c @@ -21,8 +21,16 @@ } EXPORT_SYMBOL(default_unplug_io_fn); +/* + * Convienent macros for min/max read-ahead pages. + * Note that MAX_RA_PAGES is rounded down, while MIN_RA_PAGES is rounded up. + * The latter is necessary for systems with large page size(i.e. 64k). + */ +#define MAX_RA_PAGES (VM_MAX_READAHEAD*1024 / PAGE_CACHE_SIZE) +#define MIN_RA_PAGES DIV_ROUND_UP(VM_MIN_READAHEAD*1024, PAGE_CACHE_SIZE) + struct backing_dev_info default_backing_dev_info = { - .ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE, + .ra_pages = MAX_RA_PAGES, .state = 0, .capabilities = BDI_CAP_MAP_COPY, .unplug_io_fn = default_unplug_io_fn, @@ -51,7 +59,7 @@ static inline unsigned long get_min_readahead(struct file_ra_state *ra) { - return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE; + return MIN_RA_PAGES; } static inline void reset_ahead_window(struct file_ra_state *ra) --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/unionfs/usage.txt +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/unionfs/usage.txt @@ -0,0 +1,97 @@ +Unionfs is a stackable unification file system, which can appear to merge +the contents of several directories (branches), while keeping their physical +content separate. Unionfs is useful for unified source tree management, +merged contents of split CD-ROM, merged separate software package +directories, data grids, and more. Unionfs allows any mix of read-only and +read-write branches, as well as insertion and deletion of branches anywhere +in the fan-out. To maintain Unix semantics, Unionfs handles elimination of +duplicates, partial-error conditions, and more. + +# mount -t unionfs -o branch-option[,union-options[,...]] none MOUNTPOINT + +The available branch-option for the mount command is: + + dirs=branch[=ro|=rw][:...] + +specifies a separated list of which directories compose the union. +Directories that come earlier in the list have a higher precedence than +those which come later. Additionally, read-only or read-write permissions of +the branch can be specified by appending =ro or =rw (default) to each +directory. + +Syntax: + + dirs=/branch1[=ro|=rw]:/branch2[=ro|=rw]:...:/branchN[=ro|=rw] + +Example: + + dirs=/writable_branch=rw:/read-only_branch=ro + + +DYNAMIC BRANCH MANAGEMENT AND REMOUNTS +====================================== + +You can remount a union and change its overall mode, or reconfigure the +branches, as follows. + +To downgrade a union from read-write to read-only: + +# mount -t unionfs -o remount,ro none MOUNTPOINT + +To upgrade a union from read-only to read-write: + +# mount -t unionfs -o remount,rw none MOUNTPOINT + +To delete a branch /foo, regardless where it is in the current union: + +# mount -t unionfs -o remount,del=/foo none MOUNTPOINT + +To insert (add) a branch /foo before /bar: + +# mount -t unionfs -o remount,add=/bar:/foo none MOUNTPOINT + +To insert (add) a branch /foo (with the "rw" mode flag) before /bar: + +# mount -t unionfs -o remount,add=/bar:/foo=rw none MOUNTPOINT + +To insert (add) a branch /foo (in "rw" mode) at the very beginning (i.e., a +new highest-priority branch), you can use the above syntax, or use a short +hand version as follows: + +# mount -t unionfs -o remount,add=/foo none MOUNTPOINT + +To append a branch to the very end (new lowest-priority branch): + +# mount -t unionfs -o remount,add=:/foo none MOUNTPOINT + +To append a branch to the very end (new lowest-priority branch), in +read-only mode: + +# mount -t unionfs -o remount,add=:/foo=ro none MOUNTPOINT + +Finally, to change the mode of one existing branch, say /foo, from read-only +to read-write, and change /bar from read-write to read-only: + +# mount -t unionfs -o remount,mode=/foo=rw,mode=/bar=ro none MOUNTPOINT + + +CACHE CONSISTENCY +================= + +If you modify any file on any of the lower branches directly, while there is +a Unionfs 2.0 mounted above any of those branches, you should tell Unionfs +to purge its caches and re-get the objects. To do that, you have to +increment the generation number of the superblock using the following +command: + +# mount -t unionfs -o remount,incgen none MOUNTPOINT + +Note that the older way of incrementing the generation number using an +ioctl, is no longer supported in Unionfs 2.0. Ioctls in general are not +encouraged. Plus, an ioctl is per-file concept, whereas the generation +number is a per-file-system concept. Worse, such an ioctl requires an open +file, which then has to be invalidated by the very nature of the generation +number increase (read: the old generation increase ioctl was pretty racy). + + +For more information, see . --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/unionfs/issues.txt +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/unionfs/issues.txt @@ -0,0 +1,12 @@ +KNOWN Unionfs 2.1 ISSUES: +========================= + +1. Unionfs should not use lookup_one_len() on the underlying f/s as it + confuses NFSv4. Currently, unionfs_lookup() passes lookup intents to the + lower file-system, this eliminates part of the problem. The remaining + calls to lookup_one_len may need to be changed to pass an intent. We are + currently introducing VFS changes to fs/namei.c's do_path_lookup() to + allow proper file lookup and opening in stackable file systems. + + +For more information, see . --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/unionfs/00-INDEX +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/unionfs/00-INDEX @@ -0,0 +1,10 @@ +00-INDEX + - this file. +concepts.txt + - A brief introduction of concepts. +issues.txt + - A summary of known issues with unionfs. +rename.txt + - Information regarding rename operations. +usage.txt + - Usage information and examples. --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/unionfs/rename.txt +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/unionfs/rename.txt @@ -0,0 +1,31 @@ +Rename is a complex beast. The following table shows which rename(2) operations +should succeed and which should fail. + +o: success +E: error (either unionfs or vfs) +X: EXDEV + +none = file does not exist +file = file is a file +dir = file is a empty directory +child= file is a non-empty directory +wh = file is a directory containing only whiteouts; this makes it logically + empty + + none file dir child wh +file o o E E E +dir o E o E o +child X E X E X +wh o E o E o + + +Renaming directories: +===================== + +Whenever a empty (either physically or logically) directory is being renamed, +the following sequence of events should take place: + +1) Remove whiteouts from both source and destination directory +2) Rename source to destination +3) Make destination opaque to prevent anything under it from showing up + --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/unionfs/concepts.txt +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/unionfs/concepts.txt @@ -0,0 +1,181 @@ +Unionfs 2.0 CONCEPTS: +===================== + +This file describes the concepts needed by a namespace unification file +system. + + +Branch Priority: +================ + +Each branch is assigned a unique priority - starting from 0 (highest +priority). No two branches can have the same priority. + + +Branch Mode: +============ + +Each branch is assigned a mode - read-write or read-only. This allows +directories on media mounted read-write to be used in a read-only manner. + + +Whiteouts: +========== + +A whiteout removes a file name from the namespace. Whiteouts are needed when +one attempts to remove a file on a read-only branch. + +Suppose we have a two-branch union, where branch 0 is read-write and branch +1 is read-only. And a file 'foo' on branch 1: + +./b0/ +./b1/ +./b1/foo + +The unified view would simply be: + +./union/ +./union/foo + +Since 'foo' is stored on a read-only branch, it cannot be removed. A +whiteout is used to remove the name 'foo' from the unified namespace. Again, +since branch 1 is read-only, the whiteout cannot be created there. So, we +try on a higher priority (lower numerically) branch and create the whiteout +there. + +./b0/ +./b0/.wh.foo +./b1/ +./b1/foo + +Later, when Unionfs traverses branches (due to lookup or readdir), it +eliminate 'foo' from the namespace (as well as the whiteout itself.) + + +Duplicate Elimination: +====================== + +It is possible for files on different branches to have the same name. +Unionfs then has to select which instance of the file to show to the user. +Given the fact that each branch has a priority associated with it, the +simplest solution is to take the instance from the highest priority +(numerically lowest value) and "hide" the others. + + +Copyup: +======= + +When a change is made to the contents of a file's data or meta-data, they +have to be stored somewhere. The best way is to create a copy of the +original file on a branch that is writable, and then redirect the write +though to this copy. The copy must be made on a higher priority branch so +that lookup and readdir return this newer "version" of the file rather than +the original (see duplicate elimination). + + +Cache Coherency: +================ + +Unionfs users often want to be able to modify files and directories directly +on the lower branches, and have those changes be visible at the Unionfs +level. This means that data (e.g., pages) and meta-data (dentries, inodes, +open files, etc.) have to be synchronized between the upper and lower +layers. In other words, the newest changes from a layer below have to be +propagated to the Unionfs layer above. If the two layers are not in sync, a +cache incoherency ensues, which could lead to application failures and even +oopses. The Linux kernel, however, has a rather limited set of mechanisms +to ensure this inter-layer cache coherency---so Unionfs has to do most of +the hard work on its own. + +Maintaining Invariants: + +The way Unionfs ensures cache coherency is as follows. At each entry point +to a Unionfs file system method, we call a utility function to validate the +primary objects of this method. Generally, we call unionfs_file_revalidate +on open files, and __Unionfs_d_revalidate_chain on dentries (which also +validates inodes). These utility functions check to see whether the upper +Unionfs object is in sync with any of the lower objects that it represents. +The checks we perform include whether the Unionfs superblock has a newer +generation number, or if any of the lower objects mtime's or ctime's are +newer. (Note: generation numbers change when branch-management commands are +issued, so in a way, maintaining cache coherency is also very important for +branch-management.) If indeed we determine that any Unionfs object is no +longer in sync with its lower counterparts, then we rebuild that object +similarly to how we do so for branch-management. + +While rebuilding Unionfs's objects, we also purge any page mappings and +truncate inode pages (see fs/Unionfs/dentry.c:purge_inode_data). This is to +ensure that Unionfs will re-get the newer data from the lower branches. We +perform this purging only if the Unionfs operation in question is a reading +operation; if Unionfs is performing a data writing operation (e.g., ->write, +->commit_write, etc.) then we do NOT flush the lower mappings/pages: this is +because (1) a self-deadlock could occur and (2) the upper Unionfs pages are +considered more authoritative anyway, as they are newer and will overwrite +any lower pages. + +Unionfs maintains the following important invariant regarding mtime's, +ctime's, and atime's: the upper inode object's times are the max() of all of +the lower ones. For non-directory objects, there's only one object below, +so the mapping is simple; for directory objects, there could me multiple +lower objects and we have to sync up with the newest one of all the lower +ones. This invariant is important to maintain, especially for directories +(besides, we need this to be POSIX compliant). A union could comprise +multiple writable branches, each of which could change. If we don't reflect +the newest possible mtime/ctime, some applications could fail. For example, +NFSv2/v3 exports check for newer directory mtimes on the server to determine +if the client-side attribute cache should be purged. + +To maintain these important invariants, of course, Unionfs carefully +synchronizes upper and lower times in various places. For example, if we +copy-up a file to a top-level branch, the parent directory where the file +was copied up to will now have a new mtime: so after a successful copy-up, +we sync up with the new top-level branch's parent directory mtime. + +Implementation: + +This cache-coherency implementation is efficient because it defers any +synchronizing between the upper and lower layers until absolutely needed. +Consider the example a common situation where users perform a lot of lower +changes, such as untarring a whole package. While these take place, +typically the user doesn't access the files via Unionfs; only after the +lower changes are done, does the user try to access the lower files. With +our cache-coherency implementation, the entirety of the changes to the lower +branches will not result in a single CPU cycle spent at the Unionfs level +until the user invokes a system call that goes through Unionfs. + +We have considered two alternate cache-coherency designs. (1) Using the +dentry/inode notify functionality to register interest in finding out about +any lower changes. This is a somewhat limited and also a heavy-handed +approach which could result in many notifications to the Unionfs layer upon +each small change at the lower layer (imagine a file being modified multiple +times in rapid succession). (2) Rewriting the VFS to support explicit +callbacks from lower objects to upper objects. We began exploring such an +implementation, but found it to be very complicated--it would have resulted +in massive VFS/MM changes which are unlikely to be accepted by the LKML +community. We therefore believe that our current cache-coherency design and +implementation represent the best approach at this time. + +Limitations: + +Our implementation works in that as long as a user process will have caused +Unionfs to be called, directly or indirectly, even to just do +->d_revalidate; then we will have purged the current Unionfs data and the +process will see the new data. For example, a process that continually +re-reads the same file's data will see the NEW data as soon as the lower +file had changed, upon the next read(2) syscall (even if the file is still +open!) However, this doesn't work when the process re-reads the open file's +data via mmap(2) (unless the user unmaps/closes the file and remaps/reopens +it). Once we respond to ->readpage(s), then the kernel maps the page into +the process's address space and there doesn't appear to be a way to force +the kernel to invalidate those pages/mappings, and force the process to +re-issue ->readpage. If there's a way to invalidate active mappings and +force a ->readpage, let us know please (invalidate_inode_pages2 doesn't do +the trick). + +Our current Unionfs code has to perform many file-revalidation calls. It +would be really nice if the VFS would export an optional file system hook +->file_revalidate (similarly to dentry->d_revalidate) that will be called +before each VFS op that has a "struct file" in it. + + +For more information, see . --- linux-source-2.6.22-2.6.22.orig/Documentation/filesystems/00-INDEX +++ linux-source-2.6.22-2.6.22/Documentation/filesystems/00-INDEX @@ -84,6 +84,8 @@ - info and mount options for the UDF filesystem. ufs.txt - info on the ufs filesystem. +unionfs/ + - info on the unionfs filesystem vfat.txt - info on using the VFAT filesystem used in Windows NT and Windows 95 vfs.txt --- linux-source-2.6.22-2.6.22.orig/Documentation/dvb/get_dvb_firmware +++ linux-source-2.6.22-2.6.22/Documentation/dvb/get_dvb_firmware @@ -56,7 +56,7 @@ sub sp8870 { my $sourcefile = "tt_Premium_217g.zip"; - my $url = "http://www.technotrend.de/new/217g/$sourcefile"; + my $url = "http://www.softwarepatch.pl/9999ccd06a4813cb827dbb0005071c71/$sourcefile"; my $hash = "53970ec17a538945a6d8cb608a7b3899"; my $outfile = "dvb-fe-sp8870.fw"; my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); @@ -110,21 +110,21 @@ } sub tda10046 { - my $sourcefile = "tt_budget_217g.zip"; - my $url = "http://www.technotrend.de/new/217g/$sourcefile"; - my $hash = "6a7e1e2f2644b162ff0502367553c72d"; - my $outfile = "dvb-fe-tda10046.fw"; - my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); + my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip"; + my $url = "http://technotrend-online.com/download/software/219/$sourcefile"; + my $hash = "6a7e1e2f2644b162ff0502367553c72d"; + my $outfile = "dvb-fe-tda10046.fw"; + my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); - checkstandard(); + checkstandard(); - wgetfile($sourcefile, $url); - unzip($sourcefile, $tmpdir); - extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp"); - verify("$tmpdir/fwtmp", $hash); - copy("$tmpdir/fwtmp", $outfile); + wgetfile($sourcefile, $url); + unzip($sourcefile, $tmpdir); + extract("$tmpdir/TT_PCI_2.19h_28_11_2006/software/OEM/PCI/App/ttlcdacc.dll", 0x65389, 24478, "$tmpdir/fwtmp"); + verify("$tmpdir/fwtmp", $hash); + copy("$tmpdir/fwtmp", $outfile); - $outfile; + $outfile; } sub tda10046lifeview { --- linux-source-2.6.22-2.6.22.orig/Documentation/dsdt-initrd.txt +++ linux-source-2.6.22-2.6.22/Documentation/dsdt-initrd.txt @@ -0,0 +1,98 @@ +ACPI Custom DSDT read from initramfs + +2003 by Markuss Gaugusch < dsdt at gaugusch dot org > +Special thanks go to Thomas Renninger from SuSE, who updated the patch for +2.6.0 and later modified it to read inside initramfs +2004 - 2007 maintained by Eric Piel < eric dot piel at tremplin-utc dot net > + +This option is intended for people who would like to hack their DSDT and don't want +to recompile their kernel after every change. It can also be useful to distros +which offers pre-compiled kernels and want to allow their users to use a +modified DSDT. In the Kernel config, enable the initial RAM filesystem support +(in Device Drivers|Block Devices) and enable ACPI_CUSTOM_DSDT_INITRD at the ACPI +options (General Setup|ACPI Support|Read custom DSDT from initrd). + +A custom DSDT (Differentiated System Description Table) is useful when your +computer uses ACPI but problems occur due to broken implementation. Typically, +your computer works but there are some troubles with the hardware detection or +the power management. You can check that troubles come from errors in the DSDT by +activating the ACPI debug option and reading the logs. This table is provided +by the BIOS, therefore it might be a good idea to check for BIOS update on your +vendor website before going any further. Errors are often caused by vendors +testing their hardware only with Windows or because there is code which is +executed only on a specific OS with a specific version and Linux hasn't been +considered during the development. + +Before you run away from customising your DSDT, you should note that already +corrected tables are available for a fair amount of computers on this web-page: +http://acpi.sf.net/dsdt . If you are part of the unluckies who cannot find +their hardware in this database, you can modify your DSDT by yourself. This +process is less painful than it sounds. Download the Intel ASL +compiler/decompiler at http://www.intel.com/technology/IAPC/acpi/downloads.htm . +As root, you then have to dump your DSDT and decompile it. By using the +compiler messages as well as the kernel ACPI debug messages and the reference book +(available at the Intel website and also at http://www.acpi.info), it is quite +easy to obtain a fully working table. + +Once your new DSDT is ready you'll have to add it to an initrd so that the +kernel can read the table at the very beginning of the boot. As the file has +to be accessed very early during the boot process the initrd has to be an +initramfs. The file is contained into the initramfs under the name /DSDT.aml . +To obtain such an initrd, you might have to modify your mkinitrd script or you +can add it later to the initrd with the script appended to this document. The +command will look like: +initrd-add-dsdt initrd.img my-dsdt.aml + +In case you don't use any initrd, the possibilities you have are to either start +using one (try mkinitrd or yaird), or use the "Include Custom DSDT" configure +option to directly include your DSDT inside the kernel. + +The message "Looking for DSDT in initramfs..." will tell you if the DSDT was +found or not. If you need to update your DSDT, generate a new initrd and +perform the steps above. Don't forget that with Lilo, you'll have to re-run it. + + +======================= Here starts initrd-add-dsdt =============================== +#!/bin/bash +# Adds a DSDT file to the initrd (if it's an initramfs) +# first argument is the name of archive +# second argurment is the name of the file to add +# The file will be copied as /DSDT.aml + +# 20060126: fix "Premature end of file" with some old cpio (Roland Robic) +# 20060205: this time it should really work + +# check the arguments +if [ $# -ne 2 ]; then + program_name=$(basename $0) + echo "\ +$program_name: too few arguments +Usage: $program_name initrd-name.img DSDT-to-add.aml +Adds a DSDT file to an initrd (in initramfs format) + + initrd-name.img: filename of the initrd in initramfs format + DSDT-to-add.aml: filename of the DSDT file to add + " 1>&2 + exit 1 +fi + +# we should check it's an initramfs + +tempcpio=$(mktemp -d) +# cleanup on exit, hangup, interrupt, quit, termination +trap 'rm -rf $tempcpio' 0 1 2 3 15 + +# extract the archive +gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 + +# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" +cp -f "$2" "$tempcpio"/DSDT.aml + +# add the file +cd "$tempcpio" +(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 +cd "$OLDPWD" + +# re-compress the archive +gzip -c "$tempcpio"/initramfs.cpio > "$1" + --- linux-source-2.6.22-2.6.22.orig/Documentation/kernel-parameters.txt +++ linux-source-2.6.22-2.6.22/Documentation/kernel-parameters.txt @@ -850,11 +850,6 @@ lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip Format: addr:,irq: - legacy_serial.force [HW,IA-32,X86-64] - Probe for COM ports at legacy addresses even - if PNPBIOS or ACPI should describe them. This - is for working around firmware defects. - llsc*= [IA64] See function print_params() in arch/ia64/sn/kernel/llsc4.c. @@ -1312,6 +1307,8 @@ Mechanism 1. conf2 [IA-32] Force use of PCI Configuration Mechanism 2. + mmconf [IA-32,X86_64] Enable use of MMCONFIG for PCI + Configuration nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI Configuration nomsi [MSI] If the PCI_MSI kernel config parameter is --- linux-source-2.6.22-2.6.22.orig/crypto/blkcipher.c +++ linux-source-2.6.22-2.6.22/crypto/blkcipher.c @@ -59,11 +59,13 @@ scatterwalk_unmap(walk->dst.virt.addr, 1); } +/* Get a spot of the specified length that does not straddle a page. + * The caller needs to ensure that there is enough space for this operation. + */ static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len) { - if (offset_in_page(start + len) < len) - return (u8 *)((unsigned long)(start + len) & PAGE_MASK); - return start; + u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK); + return start > end_page ? start : end_page; } static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm, @@ -155,7 +157,8 @@ if (walk->buffer) goto ok; - n = bsize * 2 + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); + n = bsize * 3 - (alignmask + 1) + + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); walk->buffer = kmalloc(n, GFP_ATOMIC); if (!walk->buffer) return blkcipher_walk_done(desc, walk, -ENOMEM); --- linux-source-2.6.22-2.6.22.orig/sound/oss/via82cxxx_audio.c +++ linux-source-2.6.22-2.6.22/sound/oss/via82cxxx_audio.c @@ -2104,6 +2104,7 @@ { struct via_info *card = vma->vm_private_data; struct via_channel *chan = &card->ch_out; + unsigned long max_bufs; struct page *dmapage; unsigned long pgoff; int rd, wr; @@ -2127,14 +2128,11 @@ rd = card->ch_in.is_mapped; wr = card->ch_out.is_mapped; -#ifndef VIA_NDEBUG - { - unsigned long max_bufs = chan->frag_number; - if (rd && wr) max_bufs *= 2; - /* via_dsp_mmap() should ensure this */ - assert (pgoff < max_bufs); - } -#endif + max_bufs = chan->frag_number; + if (rd && wr) + max_bufs *= 2; + if (pgoff >= max_bufs) + return NOPAGE_SIGBUS; /* if full-duplex (read+write) and we have two sets of bufs, * then the playback buffers come first, sez soundcard.c */ --- linux-source-2.6.22-2.6.22.orig/sound/core/seq/oss/seq_oss_synth.c +++ linux-source-2.6.22-2.6.22/sound/core/seq/oss/seq_oss_synth.c @@ -599,6 +599,9 @@ { struct seq_oss_synth *rec; + if (dev < 0 || dev >= dp->max_synthdev) + return -ENXIO; + if (dp->synths[dev].is_midi) { struct midi_info minf; snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); --- linux-source-2.6.22-2.6.22.orig/sound/core/memalloc.c +++ linux-source-2.6.22-2.6.22/sound/core/memalloc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -481,53 +482,54 @@ #define SND_MEM_PROC_FILE "driver/snd-page-alloc" static struct proc_dir_entry *snd_mem_proc; -static int snd_mem_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int snd_mem_proc_read(struct seq_file *seq, void *offset) { - int len = 0; long pages = snd_allocated_pages >> (PAGE_SHIFT-12); struct snd_mem_list *mem; int devno; static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; mutex_lock(&list_mutex); - len += snprintf(page + len, count - len, - "pages : %li bytes (%li pages per %likB)\n", - pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); + seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", + pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); devno = 0; list_for_each_entry(mem, &mem_list_head, list) { devno++; - len += snprintf(page + len, count - len, - "buffer %d : ID %08x : type %s\n", - devno, mem->id, types[mem->buffer.dev.type]); - len += snprintf(page + len, count - len, - " addr = 0x%lx, size = %d bytes\n", - (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); + seq_printf(seq, "buffer %d : ID %08x : type %s\n", + devno, mem->id, types[mem->buffer.dev.type]); + seq_printf(seq, " addr = 0x%lx, size = %d bytes\n", + (unsigned long)mem->buffer.addr, + (int)mem->buffer.bytes); } mutex_unlock(&list_mutex); - return len; + return 0; +} + +static int snd_mem_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, snd_mem_proc_read, NULL); } /* FIXME: for pci only - other bus? */ #ifdef CONFIG_PCI #define gettoken(bufp) strsep(bufp, " \t\n") -static int snd_mem_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer, + size_t count, loff_t * ppos) { char buf[128]; char *token, *p; - if (count > ARRAY_SIZE(buf) - 1) - count = ARRAY_SIZE(buf) - 1; + if (count > sizeof(buf) - 1) + return -EINVAL; if (copy_from_user(buf, buffer, count)) return -EFAULT; - buf[ARRAY_SIZE(buf) - 1] = '\0'; + buf[count] = '\0'; p = buf; token = gettoken(&p); if (! token || *token == '#') - return (int)count; + return count; if (strcmp(token, "add") == 0) { char *endp; int vendor, device, size, buffers; @@ -548,7 +550,7 @@ (buffers = simple_strtol(token, NULL, 0)) <= 0 || buffers > 4) { printk(KERN_ERR "snd-page-alloc: invalid proc write format\n"); - return (int)count; + return count; } vendor &= 0xffff; device &= 0xffff; @@ -560,7 +562,7 @@ if (pci_set_dma_mask(pci, mask) < 0 || pci_set_consistent_dma_mask(pci, mask) < 0) { printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device); - return (int)count; + return count; } } for (i = 0; i < buffers; i++) { @@ -570,7 +572,7 @@ size, &dmab) < 0) { printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size); pci_dev_put(pci); - return (int)count; + return count; } snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci)); } @@ -596,9 +598,21 @@ free_all_reserved_pages(); else printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n"); - return (int)count; + return count; } #endif /* CONFIG_PCI */ + +static const struct file_operations snd_mem_proc_fops = { + .owner = THIS_MODULE, + .open = snd_mem_proc_open, + .read = seq_read, +#ifdef CONFIG_PCI + .write = snd_mem_proc_write, +#endif + .llseek = seq_lseek, + .release = single_release, +}; + #endif /* CONFIG_PROC_FS */ /* @@ -609,12 +623,8 @@ { #ifdef CONFIG_PROC_FS snd_mem_proc = create_proc_entry(SND_MEM_PROC_FILE, 0644, NULL); - if (snd_mem_proc) { - snd_mem_proc->read_proc = snd_mem_proc_read; -#ifdef CONFIG_PCI - snd_mem_proc->write_proc = snd_mem_proc_write; -#endif - } + if (snd_mem_proc) + snd_mem_proc->proc_fops = &snd_mem_proc_fops; #endif return 0; } --- linux-source-2.6.22-2.6.22.orig/sound/pci/hda/hda_intel.c +++ linux-source-2.6.22-2.6.22/sound/pci/hda/hda_intel.c @@ -72,6 +72,12 @@ module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); +/* For workaround Poulsbo SI bugs, it affects stream descriptor offset and + * corresponding control bits + */ +static int sd_offset_fixup; +static int sd_bit_fixup; + /* just for backward compatibility */ static int enable; @@ -79,21 +85,21 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," - "{Intel, ICH6M}," - "{Intel, ICH7}," - "{Intel, ESB2}," - "{Intel, ICH8}," - "{Intel, ICH9}," - "{ATI, SB450}," - "{ATI, SB600}," - "{ATI, RS600}," - "{ATI, RS690}," - "{ATI, RS780}," - "{ATI, R600}," - "{VIA, VT8251}," - "{VIA, VT8237A}," - "{SiS, SIS966}," - "{ULI, M5461}}"); + "{Intel, ICH6M}," + "{Intel, ICH7}," + "{Intel, ESB2}," + "{Intel, ICH8}," + "{Intel, ICH9}," + "{ATI, SB450}," + "{ATI, SB600}," + "{ATI, RS600}," + "{ATI, RS690}," + "{ATI, RS780}," + "{ATI, R600}," + "{VIA, VT8251}," + "{VIA, VT8237A}," + "{SiS, SIS966}," + "{ULI, M5461}}"); MODULE_DESCRIPTION("Intel HDA driver"); #define SFX "hda-intel: " @@ -252,6 +258,10 @@ /* Defines for Nvidia HDA support */ #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f +/* Defines for Intel SCH HDA snoop control */ +#define INTEL_SCH_HDA_DEVC 0x78 +#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) + /* */ @@ -367,30 +377,30 @@ /* * macros for easy use */ -#define azx_writel(chip,reg,value) \ +#define azx_writel(chip, reg, value) \ writel(value, (chip)->remap_addr + ICH6_REG_##reg) -#define azx_readl(chip,reg) \ +#define azx_readl(chip, reg) \ readl((chip)->remap_addr + ICH6_REG_##reg) -#define azx_writew(chip,reg,value) \ +#define azx_writew(chip, reg, value) \ writew(value, (chip)->remap_addr + ICH6_REG_##reg) -#define azx_readw(chip,reg) \ +#define azx_readw(chip, reg) \ readw((chip)->remap_addr + ICH6_REG_##reg) -#define azx_writeb(chip,reg,value) \ +#define azx_writeb(chip, reg, value) \ writeb(value, (chip)->remap_addr + ICH6_REG_##reg) -#define azx_readb(chip,reg) \ +#define azx_readb(chip, reg) \ readb((chip)->remap_addr + ICH6_REG_##reg) -#define azx_sd_writel(dev,reg,value) \ +#define azx_sd_writel(dev, reg, value) \ writel(value, (dev)->sd_addr + ICH6_REG_##reg) -#define azx_sd_readl(dev,reg) \ +#define azx_sd_readl(dev, reg) \ readl((dev)->sd_addr + ICH6_REG_##reg) -#define azx_sd_writew(dev,reg,value) \ +#define azx_sd_writew(dev, reg, value) \ writew(value, (dev)->sd_addr + ICH6_REG_##reg) -#define azx_sd_readw(dev,reg) \ +#define azx_sd_readw(dev, reg) \ readw((dev)->sd_addr + ICH6_REG_##reg) -#define azx_sd_writeb(dev,reg,value) \ +#define azx_sd_writeb(dev, reg, value) \ writeb(value, (dev)->sd_addr + ICH6_REG_##reg) -#define azx_sd_readb(dev,reg) \ +#define azx_sd_readb(dev, reg) \ readb((dev)->sd_addr + ICH6_REG_##reg) /* for pcm support */ @@ -528,7 +538,7 @@ struct azx *chip = codec->bus->private_data; unsigned long timeout; - again: +again: timeout = jiffies + msecs_to_jiffies(1000); do { if (chip->polling_mode) { @@ -759,8 +769,19 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev) { /* enable SIE */ - azx_writeb(chip, INTCTL, - azx_readb(chip, INTCTL) | (1 << azx_dev->index)); + if (!sd_bit_fixup) { + azx_writel(chip, INTCTL, + azx_readl(chip, INTCTL) | (1 << azx_dev->index)); + } else { + if (azx_dev->index < sd_bit_fixup) { + azx_writel(chip, INTCTL, + azx_readl(chip, INTCTL) | (1 << azx_dev->index)); + } else { + azx_writel(chip, INTCTL, + azx_readl(chip, INTCTL) | + (1 << (azx_dev->index+sd_bit_fixup))); + } + } /* set DMA start and interrupt mask */ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_DMA_START | SD_INT_MASK); @@ -774,8 +795,19 @@ ~(SD_CTL_DMA_START | SD_INT_MASK)); azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ /* disable SIE */ - azx_writeb(chip, INTCTL, - azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); + if (!sd_bit_fixup) { + azx_writeb(chip, INTCTL, + azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); + } else { + if (azx_dev->index < sd_bit_fixup ) { + azx_writeb(chip, INTCTL, + azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); + } else { + azx_writeb(chip, INTCTL, + azx_readb(chip, INTCTL) & ~(1 << (azx_dev->index+sd_bit_fixup))); + + } + } } @@ -785,7 +817,7 @@ static void azx_init_chip(struct azx *chip) { unsigned char reg; - + unsigned short reg16; /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio codecs @@ -822,6 +854,22 @@ pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS); break; + case AZX_DRIVER_ICH: + /* Snoop is disabled in SCH (Poulsbo) at reset, enable it */ + if (chip->pci->device == PCI_DEVICE_ID_INTEL_POULSBO_HDA) { + pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ + ®16); + if (reg16 & INTEL_SCH_HDA_DEVC_NOSNOOP ) { + pci_write_config_word(chip->pci, + INTEL_SCH_HDA_DEVC, \ + reg16 & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); + pci_read_config_word(chip->pci, + INTEL_SCH_HDA_DEVC, ®16); + snd_printk(KERN_INFO "HDA snoop disabled, try to enable ... %s\n", \ + (reg16&INTEL_SCH_HDA_DEVC_NOSNOOP)? "Failed" : "OK"); + } + } + break; } } @@ -1396,11 +1444,24 @@ struct azx_dev *azx_dev = &chip->azx_dev[i]; azx_dev->bdl = (u32 *)(chip->bdl.area + off); azx_dev->bdl_addr = chip->bdl.addr + off; - azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8); /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ - azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); - /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ - azx_dev->sd_int_sta_mask = 1 << i; + if (!sd_bit_fixup) { + azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8); + azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); + /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ + azx_dev->sd_int_sta_mask = 1 << i; + } else { + if (i < sd_bit_fixup) { + azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8); + azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); + azx_dev->sd_int_sta_mask = 1 << i; + } else { + azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80 + sd_offset_fixup); + azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + (2+i) * 8); + azx_dev->sd_int_sta_mask = 1 << (i+sd_bit_fixup); + } + } + /* stream tag: must be non-zero and unique */ azx_dev->index = i; azx_dev->stream_tag = i + 1; @@ -1566,9 +1627,11 @@ { struct azx *chip; int err; + unsigned short stepping; static struct snd_device_ops ops = { .dev_free = azx_dev_free, }; + unsigned short gcap; *rchip = NULL; @@ -1646,10 +1709,39 @@ chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX; break; default: - chip->playback_streams = ICH6_NUM_PLAYBACK; - chip->capture_streams = ICH6_NUM_CAPTURE; - chip->playback_index_offset = ICH6_PLAYBACK_INDEX; - chip->capture_index_offset = ICH6_CAPTURE_INDEX; + /* read number of streams from GCAP regiser instead of using + * hardcoded value + */ + gcap = azx_readw(chip, GCAP); + if (!gcap) { + snd_printk(KERN_ERR "Device has no streams \n"); + goto errout; + }; + chip->playback_streams = (gcap&(0xF<<12))>>12; + chip->capture_streams = (gcap&(0xF<<8))>>8; + chip->playback_index_offset = (gcap&(0xF<<12))>>12; + chip->capture_index_offset = 0; + /* do fixup for poulsbo */ + if (pci->device == PCI_DEVICE_ID_INTEL_POULSBO_HDA) { + snd_printk(KERN_INFO "Do fixup for Poulsbo "); + pci_bus_read_config_word(pci->bus, 0, 0x8, &stepping); + switch (stepping) { + case 0: + /* A2 has wrong OSD0 offset and control bits */ + snd_printk(KERN_INFO "A2 stepping\n"); + sd_offset_fixup = 0x40; + sd_bit_fixup = 0x2; + break; + case 2: + /* B0 moved OSD0 offset but not control bits */ + snd_printk(KERN_INFO "B0 stepping\n"); + sd_bit_fixup = 0x2; + break; + default: + snd_printk(KERN_ERR "Unknow stepping\n"); + break; + } + } break; } chip->num_streams = chip->playback_streams + chip->capture_streams; @@ -1703,7 +1795,7 @@ *rchip = chip; return 0; - errout: +errout: azx_free(chip); return err; } @@ -1771,6 +1863,7 @@ { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ { 0x8086, 0x293e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH9 */ { 0x8086, 0x293f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH9 */ + { 0x8086, 0x811b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* POULSBO */ { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ --- linux-source-2.6.22-2.6.22.orig/sound/pci/hda/patch_sigmatel.c +++ linux-source-2.6.22-2.6.22/sound/pci/hda/patch_sigmatel.c @@ -478,6 +478,8 @@ "Dell Inspiron 640m", STAC_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5, "Dell Inspiron 1501", STAC_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, + "Dell Inspiron 1420", STAC_REF), /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF), --- linux-source-2.6.22-2.6.22.orig/sound/usb/usx2y/usx2yhwdeppcm.c +++ linux-source-2.6.22-2.6.22/sound/usb/usx2y/usx2yhwdeppcm.c @@ -728,7 +728,7 @@ return -ENODEV; } area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops; - area->vm_flags |= VM_RESERVED; + area->vm_flags |= VM_RESERVED | VM_DONTEXPAND; area->vm_private_data = hw->private_data; return 0; } --- linux-source-2.6.22-2.6.22.orig/sound/usb/usx2y/usX2Yhwdep.c +++ linux-source-2.6.22-2.6.22/sound/usb/usx2y/usX2Yhwdep.c @@ -88,7 +88,7 @@ us428->us428ctls_sharedmem->CtlSnapShotLast = -2; } area->vm_ops = &us428ctls_vm_ops; - area->vm_flags |= VM_RESERVED; + area->vm_flags |= VM_RESERVED | VM_DONTEXPAND; area->vm_private_data = hw->private_data; return 0; } --- linux-source-2.6.22-2.6.22.orig/fs/dcache.c +++ linux-source-2.6.22-2.6.22/fs/dcache.c @@ -1761,92 +1761,132 @@ } /** - * d_path - return the path of a dentry + * __d_path - return the path of a dentry * @dentry: dentry to report * @vfsmnt: vfsmnt to which the dentry belongs * @root: root dentry * @rootmnt: vfsmnt to which the root dentry belongs * @buffer: buffer to return value in * @buflen: buffer length + * @fail_deleted: what to return for deleted files * - * Convert a dentry into an ASCII path name. If the entry has been deleted + * Convert a dentry into an ASCII path name. If the entry has been deleted, + * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise, * the string " (deleted)" is appended. Note that this is ambiguous. * - * Returns the buffer or an error code if the path was too long. + * If @dentry is not connected to @root, the path returned will be relative + * (i.e., it will not start with a slash). * - * "buflen" should be positive. Caller holds the dcache_lock. + * Returns the buffer or an error code. */ -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, - struct dentry *root, struct vfsmount *rootmnt, - char *buffer, int buflen) -{ - char * end = buffer+buflen; - char * retval; - int namelen; +char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, + struct dentry *root, struct vfsmount *rootmnt, + char *buffer, int buflen, int fail_deleted) +{ + int namelen, is_slash, vfsmount_locked = 0; + + if (buflen < 2) + return ERR_PTR(-ENAMETOOLONG); + buffer += --buflen; + *buffer = '\0'; - *--end = '\0'; - buflen--; + spin_lock(&dcache_lock); if (!IS_ROOT(dentry) && d_unhashed(dentry)) { - buflen -= 10; - end -= 10; - if (buflen < 0) + if (fail_deleted) { + buffer = ERR_PTR(-ENOENT); + goto out; + } + if (buflen < 10) goto Elong; - memcpy(end, " (deleted)", 10); + buflen -= 10; + buffer -= 10; + memcpy(buffer, " (deleted)", 10); } - - if (buflen < 1) - goto Elong; - /* Get '/' right */ - retval = end-1; - *retval = '/'; - - for (;;) { + while (dentry != root || vfsmnt != rootmnt) { struct dentry * parent; - if (dentry == root && vfsmnt == rootmnt) - break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { - /* Global root? */ - spin_lock(&vfsmount_lock); - if (vfsmnt->mnt_parent == vfsmnt) { - spin_unlock(&vfsmount_lock); - goto global_root; + if (!vfsmount_locked) { + spin_lock(&vfsmount_lock); + vfsmount_locked = 1; } + if (vfsmnt->mnt_parent == vfsmnt) + goto global_root; dentry = vfsmnt->mnt_mountpoint; vfsmnt = vfsmnt->mnt_parent; - spin_unlock(&vfsmount_lock); continue; } parent = dentry->d_parent; prefetch(parent); namelen = dentry->d_name.len; - buflen -= namelen + 1; - if (buflen < 0) + if (buflen < namelen + 1) goto Elong; - end -= namelen; - memcpy(end, dentry->d_name.name, namelen); - *--end = '/'; - retval = end; + buflen -= namelen + 1; + buffer -= namelen; + memcpy(buffer, dentry->d_name.name, namelen); + *--buffer = '/'; dentry = parent; } + /* Get '/' right. */ + if (*buffer != '/') + *--buffer = '/'; - return retval; +out: + if (vfsmount_locked) + spin_unlock(&vfsmount_lock); + spin_unlock(&dcache_lock); + return buffer; global_root: + /* + * We went past the (vfsmount, dentry) we were looking for and have + * either hit a root dentry, a lazily unmounted dentry, an + * unconnected dentry, or the file is on a pseudo filesystem. + */ namelen = dentry->d_name.len; - buflen -= namelen; - if (buflen < 0) + is_slash = (namelen == 1 && *dentry->d_name.name == '/'); + if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) { + /* + * Make sure we won't return a pathname starting with '/'. + * + * Historically, we also glue together the root dentry and + * remaining name for pseudo filesystems like pipefs, which + * have the MS_NOUSER flag set. This results in pathnames + * like "pipe:[439336]". + */ + if (*buffer == '/') { + buffer++; + buflen++; + } + if (is_slash) + goto out; + } + if (buflen < namelen) goto Elong; - retval -= namelen-1; /* hit the slash */ - memcpy(retval, dentry->d_name.name, namelen); - return retval; + buffer -= namelen; + memcpy(buffer, dentry->d_name.name, namelen); + goto out; + Elong: - return ERR_PTR(-ENAMETOOLONG); + buffer = ERR_PTR(-ENAMETOOLONG); + goto out; +} + +static char *__connect_d_path(char *path, char *buffer) +{ + if (!IS_ERR(path) && *path != '/') { + /* Pretend that disconnected paths are hanging off the root. */ + if (path == buffer) + path = ERR_PTR(-ENAMETOOLONG); + else + *--path = '/'; + } + return path; } /* write full pathname into buffer and return start of pathname */ -char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, - char *buf, int buflen) +char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, + int buflen) { char *res; struct vfsmount *rootmnt; @@ -1866,9 +1906,8 @@ rootmnt = mntget(current->fs->rootmnt); root = dget(current->fs->root); read_unlock(¤t->fs->lock); - spin_lock(&dcache_lock); - res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); - spin_unlock(&dcache_lock); + res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0); + res = __connect_d_path(res, buf); dput(root); mntput(rootmnt); return res; @@ -1915,10 +1954,10 @@ */ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) { - int error; + int error, len; struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; - char *page = (char *) __get_free_page(GFP_USER); + char *page = (char *) __get_free_page(GFP_USER), *cwd; if (!page) return -ENOMEM; @@ -1930,29 +1969,19 @@ root = dget(current->fs->root); read_unlock(¤t->fs->lock); - error = -ENOENT; - /* Has the current directory has been unlinked? */ - spin_lock(&dcache_lock); - if (pwd->d_parent == pwd || !d_unhashed(pwd)) { - unsigned long len; - char * cwd; - - cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); - spin_unlock(&dcache_lock); - - error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; - - error = -ERANGE; - len = PAGE_SIZE + page - cwd; - if (len <= size) { - error = len; - if (copy_to_user(buf, cwd, len)) - error = -EFAULT; - } - } else - spin_unlock(&dcache_lock); + cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1); + cwd = __connect_d_path(cwd, page); + error = PTR_ERR(cwd); + if (IS_ERR(cwd)) + goto out; + + error = -ERANGE; + len = PAGE_SIZE + page - cwd; + if (len <= size) { + error = len; + if (copy_to_user(buf, cwd, len)) + error = -EFAULT; + } out: dput(pwd); --- linux-source-2.6.22-2.6.22.orig/fs/fat/file.c +++ linux-source-2.6.22-2.6.22/fs/fat/file.c @@ -92,7 +92,7 @@ } /* This MUST be done before doing anything irreversible... */ - err = notify_change(filp->f_path.dentry, &ia); + err = notify_change(filp->f_path.dentry, filp->f_path.mnt, &ia); if (err) goto up; --- linux-source-2.6.22-2.6.22.orig/fs/ntfs/file.c +++ linux-source-2.6.22-2.6.22/fs/ntfs/file.c @@ -2122,7 +2122,7 @@ goto out; if (!count) goto out; - err = remove_suid(file->f_path.dentry); + err = remove_suid(&file->f_path); if (err) goto out; file_update_time(file); --- linux-source-2.6.22-2.6.22.orig/fs/signalfd.c +++ linux-source-2.6.22-2.6.22/fs/signalfd.c @@ -56,12 +56,18 @@ sighand = lock_task_sighand(lk->tsk, &lk->flags); rcu_read_unlock(); - if (sighand && !ctx->tsk) { + if (!sighand) + return 0; + + if (!ctx->tsk) { unlock_task_sighand(lk->tsk, &lk->flags); - sighand = NULL; + return 0; } - return sighand != NULL; + if (lk->tsk->tgid == current->tgid) + lk->tsk = current; + + return 1; } static void signalfd_unlock(struct signalfd_lockctx *lk) @@ -331,7 +337,7 @@ init_waitqueue_head(&ctx->wqh); ctx->sigmask = sigmask; - ctx->tsk = current; + ctx->tsk = current->group_leader; sighand = current->sighand; /* --- linux-source-2.6.22-2.6.22.orig/fs/ncpfs/mmap.c +++ linux-source-2.6.22-2.6.22/fs/ncpfs/mmap.c @@ -47,9 +47,6 @@ pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT); count = PAGE_SIZE; - if (address + PAGE_SIZE > area->vm_end) { - count = area->vm_end - address; - } /* what we can read in one go */ bufsize = NCP_SERVER(inode)->buffer_size; --- linux-source-2.6.22-2.6.22.orig/fs/timerfd.c +++ linux-source-2.6.22-2.6.22/fs/timerfd.c @@ -95,7 +95,7 @@ { struct timerfd_ctx *ctx = file->private_data; ssize_t res; - u32 ticks = 0; + u64 ticks = 0; DECLARE_WAITQUEUE(wait, current); if (count < sizeof(ticks)) @@ -130,7 +130,7 @@ * callback to avoid DoS attacks specifying a very * short timer period. */ - ticks = (u32) + ticks = (u64) hrtimer_forward(&ctx->tmr, hrtimer_cb_get_time(&ctx->tmr), ctx->tintv); @@ -140,7 +140,7 @@ } spin_unlock_irq(&ctx->wqh.lock); if (ticks) - res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks); + res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks); return res; } --- linux-source-2.6.22-2.6.22.orig/fs/direct-io.c +++ linux-source-2.6.22-2.6.22/fs/direct-io.c @@ -974,6 +974,7 @@ dio->get_block = get_block; dio->end_io = end_io; dio->map_bh.b_private = NULL; + dio->map_bh.b_state = 0; dio->final_block_in_bio = -1; dio->next_block_for_io = -1; --- linux-source-2.6.22-2.6.22.orig/fs/jbd2/commit.c +++ linux-source-2.6.22-2.6.22/fs/jbd2/commit.c @@ -896,7 +896,8 @@ journal->j_committing_transaction = NULL; spin_unlock(&journal->j_state_lock); - if (commit_transaction->t_checkpoint_list == NULL) { + if (commit_transaction->t_checkpoint_list == NULL && + commit_transaction->t_checkpoint_io_list == NULL) { __jbd2_journal_drop_transaction(journal, commit_transaction); } else { if (journal->j_checkpoint_transactions == NULL) { --- linux-source-2.6.22-2.6.22.orig/fs/afs/mntpt.c +++ linux-source-2.6.22-2.6.22/fs/afs/mntpt.c @@ -235,8 +235,8 @@ err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts); switch (err) { case 0: - mntput(nd->mnt); dput(nd->dentry); + mntput(nd->mnt); nd->mnt = newmnt; nd->dentry = dget(newmnt->mnt_root); schedule_delayed_work(&afs_mntpt_expiry_timer, --- linux-source-2.6.22-2.6.22.orig/fs/splice.c +++ linux-source-2.6.22-2.6.22/fs/splice.c @@ -601,7 +601,7 @@ ret = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); if (unlikely(ret)) - goto out; + goto out_release; } ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); @@ -657,8 +657,9 @@ */ mark_page_accessed(page); out: - page_cache_release(page); unlock_page(page); +out_release: + page_cache_release(page); out_ret: return ret; } @@ -807,7 +808,7 @@ ssize_t ret; int err; - err = remove_suid(out->f_path.dentry); + err = remove_suid(&out->f_path); if (unlikely(err)) return err; @@ -860,7 +861,7 @@ err = should_remove_suid(out->f_path.dentry); if (unlikely(err)) { mutex_lock(&inode->i_mutex); - err = __remove_suid(out->f_path.dentry, err); + err = __remove_suid(&out->f_path, err); mutex_unlock(&inode->i_mutex); if (err) return err; @@ -1010,7 +1011,7 @@ max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); ret = do_splice_to(in, ppos, pipe, max_read_len, flags); - if (unlikely(ret < 0)) + if (unlikely(ret <= 0)) goto out_release; read_len = ret; @@ -1022,7 +1023,7 @@ */ ret = do_splice_from(pipe, out, &out_off, read_len, flags & ~SPLICE_F_NONBLOCK); - if (unlikely(ret < 0)) + if (unlikely(ret <= 0)) goto out_release; bytes += ret; @@ -1181,6 +1182,9 @@ if (unlikely(!base)) break; + if (!access_ok(VERIFY_READ, base, len)) + break; + /* * Get this base offset and number of pages, then map * in the user pages. --- linux-source-2.6.22-2.6.22.orig/fs/proc/proc_misc.c +++ linux-source-2.6.22-2.6.22/fs/proc/proc_misc.c @@ -623,6 +623,19 @@ return proc_calc_metrics(page, start, off, count, eof, len); } +#ifdef CONFIG_VERSION_SIGNATURE +static int version_signature_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + strcpy(page, CONFIG_VERSION_SIGNATURE); + strcat(page, "\n"); + len = strlen(page); + return proc_calc_metrics(page, start, off, count, eof, len); +} +#endif + #ifdef CONFIG_MAGIC_SYSRQ /* * writing 'C' to /proc/sysrq-trigger is like sysrq-C @@ -675,6 +688,9 @@ {"cmdline", cmdline_read_proc}, {"locks", locks_read_proc}, {"execdomains", execdomains_read_proc}, +#ifdef CONFIG_VERSION_SIGNATURE + {"version_signature", version_signature_read_proc}, +#endif {NULL,} }; for (p = simple_ones; p->name; p++) --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/os-linux.h +++ linux-source-2.6.22-2.6.22/fs/jffs2/os-linux.h @@ -173,12 +173,15 @@ extern const struct inode_operations jffs2_symlink_inode_operations; /* fs.c */ +struct posix_acl; + int jffs2_setattr (struct dentry *, struct iattr *); +int jffs2_do_setattr (struct inode *, struct iattr *); void jffs2_read_inode (struct inode *); void jffs2_clear_inode (struct inode *); void jffs2_dirty_inode(struct inode *inode); struct inode *jffs2_new_inode (struct inode *dir_i, int mode, - struct jffs2_raw_inode *ri); + struct jffs2_raw_inode *ri, struct posix_acl **acl); int jffs2_statfs (struct dentry *, struct kstatfs *); void jffs2_write_super (struct super_block *); int jffs2_remount_fs (struct super_block *, int *, char *); --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/write.c +++ linux-source-2.6.22-2.6.22/fs/jffs2/write.c @@ -553,6 +553,9 @@ struct jffs2_full_dirent **prev = &dir_f->dents; uint32_t nhash = full_name_hash(name, namelen); + /* We don't actually want to reserve any space, but we do + want to be holding the alloc_sem when we write to flash */ + down(&c->alloc_sem); down(&dir_f->sem); while ((*prev) && (*prev)->nhash <= nhash) { --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/acl.c +++ linux-source-2.6.22-2.6.22/fs/jffs2/acl.c @@ -176,7 +176,7 @@ spin_unlock(&inode->i_lock); } -static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) +struct posix_acl *jffs2_get_acl(struct inode *inode, int type) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct posix_acl *acl; @@ -247,8 +247,13 @@ if (rc < 0) return rc; if (inode->i_mode != mode) { - inode->i_mode = mode; - jffs2_dirty_inode(inode); + struct iattr attr; + + attr.ia_valid = ATTR_MODE; + attr.ia_mode = mode; + rc = jffs2_do_setattr(inode, &attr); + if (rc < 0) + return rc; } if (rc == 0) acl = NULL; @@ -307,22 +312,16 @@ return generic_permission(inode, mask, jffs2_check_acl); } -int jffs2_init_acl(struct inode *inode, struct inode *dir) +int jffs2_init_acl(struct inode *inode, struct posix_acl *acl) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct posix_acl *acl = NULL, *clone; + struct posix_acl *clone; mode_t mode; int rc = 0; f->i_acl_access = JFFS2_ACL_NOT_CACHED; f->i_acl_default = JFFS2_ACL_NOT_CACHED; - if (!S_ISLNK(inode->i_mode)) { - acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (!acl) - inode->i_mode &= ~current->fs->umask; - } + if (acl) { if (S_ISDIR(inode->i_mode)) { rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl); --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/fs.c +++ linux-source-2.6.22-2.6.22/fs/jffs2/fs.c @@ -24,7 +24,7 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c); -static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) +int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) { struct jffs2_full_dnode *old_metadata, *new_metadata; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); @@ -36,10 +36,8 @@ unsigned int ivalid; uint32_t alloclen; int ret; + D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); - ret = inode_change_ok(inode, iattr); - if (ret) - return ret; /* Special cases - we don't want more than one data node for these types on the medium at any time. So setattr @@ -183,9 +181,14 @@ { int rc; + rc = inode_change_ok(dentry->d_inode, iattr); + if (rc) + return rc; + rc = jffs2_do_setattr(dentry->d_inode, iattr); if (!rc && (iattr->ia_valid & ATTR_MODE)) rc = jffs2_acl_chmod(dentry->d_inode); + return rc; } @@ -399,7 +402,8 @@ /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ -struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) +struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri, + struct posix_acl **acl) { struct inode *inode; struct super_block *sb = dir_i->i_sb; @@ -431,7 +435,23 @@ } else { ri->gid = cpu_to_je16(current->fsgid); } - ri->mode = cpu_to_jemode(mode); + + /* POSIX ACLs have to be processed now, at least partly. + The umask is only applied if there's no default ACL */ + if (!S_ISLNK(mode)) { + *acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT); + if (IS_ERR(*acl)) { + make_bad_inode(inode); + iput(inode); + inode = (void *)*acl; + *acl = NULL; + return inode; + } + if (!(*acl)) + mode &= ~current->fs->umask; + } else { + *acl = NULL; + } ret = jffs2_do_new_inode (c, f, mode, ri); if (ret) { make_bad_inode(inode); @@ -627,7 +647,7 @@ struct inode *inode = OFNI_EDONI_2SFFJ(f); struct page *pg; - pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, + pg = read_cache_page_async(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode); if (IS_ERR(pg)) return (void *)pg; --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/acl.h +++ linux-source-2.6.22-2.6.22/fs/jffs2/acl.h @@ -28,9 +28,10 @@ #define JFFS2_ACL_NOT_CACHED ((void *)-1) +extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type); extern int jffs2_permission(struct inode *, int, struct nameidata *); extern int jffs2_acl_chmod(struct inode *); -extern int jffs2_init_acl(struct inode *, struct inode *); +extern int jffs2_init_acl(struct inode *, struct posix_acl *); extern void jffs2_clear_acl(struct jffs2_inode_info *); extern struct xattr_handler jffs2_acl_access_xattr_handler; @@ -38,6 +39,7 @@ #else +#define jffs2_get_acl(inode, type) (NULL) #define jffs2_permission NULL #define jffs2_acl_chmod(inode) (0) #define jffs2_init_acl(inode,dir) (0) --- linux-source-2.6.22-2.6.22.orig/fs/jffs2/dir.c +++ linux-source-2.6.22-2.6.22/fs/jffs2/dir.c @@ -182,6 +182,7 @@ struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; struct inode *inode; + struct posix_acl *acl; int ret; ri = jffs2_alloc_raw_inode(); @@ -192,7 +193,7 @@ D1(printk(KERN_DEBUG "jffs2_create()\n")); - inode = jffs2_new_inode(dir_i, mode, ri); + inode = jffs2_new_inode(dir_i, mode, ri, &acl); if (IS_ERR(inode)) { D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); @@ -212,12 +213,12 @@ dentry->d_name.name, dentry->d_name.len); if (ret) - goto fail; + goto fail_acl; ret = jffs2_init_security(inode, dir_i); if (ret) - goto fail; - ret = jffs2_init_acl(inode, dir_i); + goto fail_acl; + ret = jffs2_init_acl(inode, acl); if (ret) goto fail; @@ -230,6 +231,8 @@ inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); return 0; + fail_acl: + posix_acl_release(acl); fail: make_bad_inode(inode); iput(inode); @@ -306,6 +309,7 @@ struct jffs2_full_dirent *fd; int namelen; uint32_t alloclen; + struct posix_acl *acl; int ret, targetlen = strlen(target); /* FIXME: If you care. We'd need to use frags for the target @@ -332,7 +336,7 @@ return ret; } - inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri); + inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri, &acl); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -362,6 +366,7 @@ up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); + posix_acl_release(acl); return PTR_ERR(fn); } @@ -372,6 +377,7 @@ up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); + posix_acl_release(acl); return -ENOMEM; } @@ -389,9 +395,10 @@ ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); + posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, dir_i); + ret = jffs2_init_acl(inode, acl); if (ret) { jffs2_clear_inode(inode); return ret; @@ -469,6 +476,7 @@ struct jffs2_full_dirent *fd; int namelen; uint32_t alloclen; + struct posix_acl *acl; int ret; mode |= S_IFDIR; @@ -491,7 +499,7 @@ return ret; } - inode = jffs2_new_inode(dir_i, mode, ri); + inode = jffs2_new_inode(dir_i, mode, ri, &acl); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -518,6 +526,7 @@ up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); + posix_acl_release(acl); return PTR_ERR(fn); } /* No data here. Only a metadata node, which will be @@ -531,9 +540,10 @@ ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); + posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, dir_i); + ret = jffs2_init_acl(inode, acl); if (ret) { jffs2_clear_inode(inode); return ret; @@ -629,6 +639,7 @@ union jffs2_device_node dev; int devlen = 0; uint32_t alloclen; + struct posix_acl *acl; int ret; if (!new_valid_dev(rdev)) @@ -655,7 +666,7 @@ return ret; } - inode = jffs2_new_inode(dir_i, mode, ri); + inode = jffs2_new_inode(dir_i, mode, ri, &acl); if (IS_ERR(inode)) { jffs2_free_raw_inode(ri); @@ -684,6 +695,7 @@ up(&f->sem); jffs2_complete_reservation(c); jffs2_clear_inode(inode); + posix_acl_release(acl); return PTR_ERR(fn); } /* No data here. Only a metadata node, which will be @@ -697,9 +709,10 @@ ret = jffs2_init_security(inode, dir_i); if (ret) { jffs2_clear_inode(inode); + posix_acl_release(acl); return ret; } - ret = jffs2_init_acl(inode, dir_i); + ret = jffs2_init_acl(inode, acl); if (ret) { jffs2_clear_inode(inode); return ret; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/meta_io.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/meta_io.c @@ -387,12 +387,18 @@ if (test_clear_buffer_pinned(bh)) { struct gfs2_trans *tr = current->journal_info; + struct gfs2_inode *bh_ip = + GFS2_I(bh->b_page->mapping->host); + gfs2_log_lock(sdp); list_del_init(&bd->bd_le.le_list); gfs2_assert_warn(sdp, sdp->sd_log_num_buf); sdp->sd_log_num_buf--; gfs2_log_unlock(sdp); - tr->tr_num_buf_rm++; + if (bh_ip->i_inode.i_private != NULL) + tr->tr_num_databuf_rm++; + else + tr->tr_num_buf_rm++; brelse(bh); } if (bd) { --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/incore.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/incore.h @@ -28,6 +28,14 @@ typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); +struct gfs2_log_header_host { + u64 lh_sequence; /* Sequence number of this transaction */ + u32 lh_flags; /* GFS2_LOG_HEAD_... */ + u32 lh_tail; /* Block number of log tail */ + u32 lh_blkno; + u32 lh_hash; +}; + /* * Structure of operations that are associated with each * type of element in the log. @@ -60,12 +68,23 @@ u32 bi_len; }; +struct gfs2_rgrp_host { + u32 rg_flags; + u32 rg_free; + u32 rg_dinodes; + u64 rg_igeneration; +}; + struct gfs2_rgrpd { struct list_head rd_list; /* Link with superblock */ struct list_head rd_list_mru; struct list_head rd_recent; /* Recently used rgrps */ struct gfs2_glock *rd_gl; /* Glock for this rgrp */ - struct gfs2_rindex_host rd_ri; + u64 rd_addr; /* grp block disk address */ + u64 rd_data0; /* first data location */ + u32 rd_length; /* length of rgrp header in fs blocks */ + u32 rd_data; /* num of data blocks in rgrp */ + u32 rd_bitbytes; /* number of bytes in data bitmaps */ struct gfs2_rgrp_host rd_rg; u64 rd_rg_vn; struct gfs2_bitmap *rd_bits; @@ -76,6 +95,8 @@ u32 rd_last_alloc_data; u32 rd_last_alloc_meta; struct gfs2_sbd *rd_sbd; + unsigned long rd_flags; +#define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */ }; enum gfs2_state_bits { @@ -211,10 +232,24 @@ GIF_SW_PAGED = 3, }; +struct gfs2_dinode_host { + u64 di_size; /* number of bytes in file */ + u64 di_blocks; /* number of blocks in file */ + u64 di_goal_meta; /* rgrp to alloc from next */ + u64 di_goal_data; /* data block goal */ + u64 di_generation; /* generation number for NFS */ + u32 di_flags; /* GFS2_DIF_... */ + u16 di_height; /* height of metadata */ + /* These only apply to directories */ + u16 di_depth; /* Number of bits in the table */ + u32 di_entries; /* The number of entries in the directory */ + u64 di_eattr; /* extended attribute block number */ +}; + struct gfs2_inode { struct inode i_inode; - struct gfs2_inum_host i_num; - + u64 i_no_addr; + u64 i_no_formal_ino; unsigned long i_flags; /* GIF_... */ struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ @@ -275,14 +310,6 @@ QDF_LOCKED = 2, }; -struct gfs2_quota_lvb { - __be32 qb_magic; - u32 __pad; - __be64 qb_limit; /* Hard limit of # blocks to alloc */ - __be64 qb_warn; /* Warn user when alloc is above this # */ - __be64 qb_value; /* Current # blocks allocated */ -}; - struct gfs2_quota_data { struct list_head qd_list; unsigned int qd_count; @@ -327,7 +354,9 @@ unsigned int tr_num_buf; unsigned int tr_num_buf_new; + unsigned int tr_num_databuf_new; unsigned int tr_num_buf_rm; + unsigned int tr_num_databuf_rm; struct list_head tr_list_buf; unsigned int tr_num_revoke; @@ -354,6 +383,12 @@ unsigned int jd_blocks; }; +struct gfs2_statfs_change_host { + s64 sc_total; + s64 sc_free; + s64 sc_dinodes; +}; + #define GFS2_GLOCKD_DEFAULT 1 #define GFS2_GLOCKD_MAX 16 @@ -426,6 +461,28 @@ #define GFS2_FSNAME_LEN 256 +struct gfs2_inum_host { + u64 no_formal_ino; + u64 no_addr; +}; + +struct gfs2_sb_host { + u32 sb_magic; + u32 sb_type; + u32 sb_format; + + u32 sb_fs_format; + u32 sb_multihost_format; + u32 sb_bsize; + u32 sb_bsize_shift; + + struct gfs2_inum_host sb_master_dir; + struct gfs2_inum_host sb_root_dir; + + char sb_lockproto[GFS2_LOCKNAME_LEN]; + char sb_locktable[GFS2_LOCKNAME_LEN]; +}; + struct gfs2_sbd { struct super_block *sd_vfs; struct super_block *sd_vfs_meta; @@ -544,6 +601,7 @@ unsigned int sd_log_blks_reserved; unsigned int sd_log_commited_buf; + unsigned int sd_log_commited_databuf; unsigned int sd_log_commited_revoke; unsigned int sd_log_num_gl; @@ -552,7 +610,6 @@ unsigned int sd_log_num_rg; unsigned int sd_log_num_databuf; unsigned int sd_log_num_jdata; - unsigned int sd_log_num_hdrs; struct list_head sd_log_le_gl; struct list_head sd_log_le_buf; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_file.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_file.c @@ -502,7 +502,7 @@ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); struct lm_lockname name = - { .ln_number = ip->i_num.no_addr, + { .ln_number = ip->i_no_addr, .ln_type = LM_TYPE_PLOCK }; if (!(fl->fl_flags & FL_POSIX)) @@ -557,7 +557,7 @@ gfs2_glock_dq_uninit(fl_gh); } else { error = gfs2_glock_get(GFS2_SB(&ip->i_inode), - ip->i_num.no_addr, &gfs2_flock_glops, + ip->i_no_addr, &gfs2_flock_glops, CREATE, &gl); if (error) goto out; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/daemon.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/daemon.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -49,6 +50,8 @@ while (!kthread_should_stop()) { gfs2_scand_internal(sdp); t = gfs2_tune_get(sdp, gt_scand_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -74,6 +77,8 @@ wait_event_interruptible(sdp->sd_reclaim_wq, (atomic_read(&sdp->sd_reclaim_count) || kthread_should_stop())); + if (freezing(current)) + refrigerator(); } return 0; @@ -93,6 +98,8 @@ while (!kthread_should_stop()) { gfs2_check_journals(sdp); t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -141,6 +148,8 @@ } t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } @@ -191,6 +200,8 @@ gfs2_quota_scan(sdp); t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; + if (freezing(current)) + refrigerator(); schedule_timeout_interruptible(t); } --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_fstype.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_fstype.h @@ -14,5 +14,6 @@ extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; +extern struct export_operations gfs2_export_ops; #endif /* __OPS_FSTYPE_DOT_H__ */ --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking.c @@ -181,4 +181,7 @@ EXPORT_SYMBOL_GPL(gfs2_register_lockproto); EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto); +EXPORT_SYMBOL_GPL(gfs2_unmount_lockproto); +EXPORT_SYMBOL_GPL(gfs2_mount_lockproto); +EXPORT_SYMBOL_GPL(gfs2_withdraw_lockproto); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/inode.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/inode.c @@ -38,12 +38,17 @@ #include "trans.h" #include "util.h" +struct gfs2_inum_range_host { + u64 ir_start; + u64 ir_length; +}; + static int iget_test(struct inode *inode, void *opaque) { struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_inum_host *inum = opaque; + u64 *no_addr = opaque; - if (ip->i_num.no_addr == inum->no_addr && + if (ip->i_no_addr == *no_addr && inode->i_private != NULL) return 1; @@ -53,37 +58,70 @@ static int iget_set(struct inode *inode, void *opaque) { struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_inum_host *inum = opaque; + u64 *no_addr = opaque; - ip->i_num = *inum; - inode->i_ino = inum->no_addr; + inode->i_ino = (unsigned long)*no_addr; + ip->i_no_addr = *no_addr; return 0; } -struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) +struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) +{ + unsigned long hash = (unsigned long)no_addr; + return ilookup5(sb, hash, iget_test, &no_addr); +} + +static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) { - return ilookup5(sb, (unsigned long)inum->no_addr, - iget_test, inum); + unsigned long hash = (unsigned long)no_addr; + return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); } -static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) +/** + * GFS2 lookup code fills in vfs inode contents based on info obtained + * from directory entry inside gfs2_inode_lookup(). This has caused issues + * with NFS code path since its get_dentry routine doesn't have the relevant + * directory entry when gfs2_inode_lookup() is invoked. Part of the code + * segment inside gfs2_inode_lookup code needs to get moved around. + * + * Clean up I_LOCK and I_NEW as well. + **/ + +void gfs2_set_iop(struct inode *inode) { - return iget5_locked(sb, (unsigned long)inum->no_addr, - iget_test, iget_set, inum); + umode_t mode = inode->i_mode; + + if (S_ISREG(mode)) { + inode->i_op = &gfs2_file_iops; + inode->i_fop = &gfs2_file_fops; + inode->i_mapping->a_ops = &gfs2_file_aops; + } else if (S_ISDIR(mode)) { + inode->i_op = &gfs2_dir_iops; + inode->i_fop = &gfs2_dir_fops; + } else if (S_ISLNK(mode)) { + inode->i_op = &gfs2_symlink_iops; + } else { + inode->i_op = &gfs2_dev_iops; + } + + unlock_new_inode(inode); } /** * gfs2_inode_lookup - Lookup an inode * @sb: The super block - * @inum: The inode number + * @no_addr: The inode number * @type: The type of the inode * * Returns: A VFS inode, or an error */ -struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) +struct inode *gfs2_inode_lookup(struct super_block *sb, + unsigned int type, + u64 no_addr, + u64 no_formal_ino) { - struct inode *inode = gfs2_iget(sb, inum); + struct inode *inode = gfs2_iget(sb, no_addr); struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_glock *io_gl; int error; @@ -93,29 +131,15 @@ if (inode->i_state & I_NEW) { struct gfs2_sbd *sdp = GFS2_SB(inode); - umode_t mode = DT2IF(type); inode->i_private = ip; - inode->i_mode = mode; + ip->i_no_formal_ino = no_formal_ino; - if (S_ISREG(mode)) { - inode->i_op = &gfs2_file_iops; - inode->i_fop = &gfs2_file_fops; - inode->i_mapping->a_ops = &gfs2_file_aops; - } else if (S_ISDIR(mode)) { - inode->i_op = &gfs2_dir_iops; - inode->i_fop = &gfs2_dir_fops; - } else if (S_ISLNK(mode)) { - inode->i_op = &gfs2_symlink_iops; - } else { - inode->i_op = &gfs2_dev_iops; - } - - error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); if (unlikely(error)) goto fail; ip->i_gl->gl_object = ip; - error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl); + error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); if (unlikely(error)) goto fail_put; @@ -123,12 +147,38 @@ error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); if (unlikely(error)) goto fail_iopen; + ip->i_iopen_gh.gh_gl->gl_object = ip; gfs2_glock_put(io_gl); - unlock_new_inode(inode); + + if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) + goto gfs2_nfsbypass; + + inode->i_mode = DT2IF(type); + + /* + * We must read the inode in order to work out its type in + * this case. Note that this doesn't happen often as we normally + * know the type beforehand. This code path only occurs during + * unlinked inode recovery (where it is safe to do this glock, + * which is not true in the general case). + */ + if (type == DT_UNKNOWN) { + struct gfs2_holder gh; + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (unlikely(error)) + goto fail_glock; + /* Inode is now uptodate */ + gfs2_glock_dq_uninit(&gh); + } + + gfs2_set_iop(inode); } +gfs2_nfsbypass: return inode; +fail_glock: + gfs2_glock_dq(&ip->i_iopen_gh); fail_iopen: gfs2_glock_put(io_gl); fail_put: @@ -144,14 +194,12 @@ struct gfs2_dinode_host *di = &ip->i_di; const struct gfs2_dinode *str = buf; - if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { + if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) { if (gfs2_consist_inode(ip)) gfs2_dinode_print(ip); return -EIO; } - if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) - return -ESTALE; - + ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); ip->i_inode.i_mode = be32_to_cpu(str->di_mode); ip->i_inode.i_rdev = 0; switch (ip->i_inode.i_mode & S_IFMT) { @@ -175,11 +223,11 @@ di->di_blocks = be64_to_cpu(str->di_blocks); gfs2_set_inode_blocks(&ip->i_inode); ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); - ip->i_inode.i_atime.tv_nsec = 0; + ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); - ip->i_inode.i_mtime.tv_nsec = 0; + ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); - ip->i_inode.i_ctime.tv_nsec = 0; + ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); di->di_goal_meta = be64_to_cpu(str->di_goal_meta); di->di_goal_data = be64_to_cpu(str->di_goal_data); @@ -247,7 +295,7 @@ if (error) goto out_qs; - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); if (!rgd) { gfs2_consist_inode(ip); error = -EIO; @@ -314,7 +362,7 @@ else drop_nlink(&ip->i_inode); - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -366,9 +414,7 @@ struct super_block *sb = dir->i_sb; struct gfs2_inode *dip = GFS2_I(dir); struct gfs2_holder d_gh; - struct gfs2_inum_host inum; - unsigned int type; - int error; + int error = 0; struct inode *inode = NULL; int unlock = 0; @@ -395,12 +441,9 @@ goto out; } - error = gfs2_dir_search(dir, name, &inum, &type); - if (error) - goto out; - - inode = gfs2_inode_lookup(sb, &inum, type); - + inode = gfs2_dir_search(dir, name); + if (IS_ERR(inode)) + error = PTR_ERR(inode); out: if (unlock) gfs2_glock_dq_uninit(&d_gh); @@ -409,6 +452,22 @@ return inode ? inode : ERR_PTR(error); } +static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) +{ + const struct gfs2_inum_range *str = buf; + + ir->ir_start = be64_to_cpu(str->ir_start); + ir->ir_length = be64_to_cpu(str->ir_length); +} + +static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) +{ + struct gfs2_inum_range *str = buf; + + str->ir_start = cpu_to_be64(ir->ir_start); + str->ir_length = cpu_to_be64(ir->ir_length); +} + static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) { struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); @@ -548,7 +607,7 @@ if (!dip->i_inode.i_nlink) return -EPERM; - error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); + error = gfs2_dir_check(&dip->i_inode, name, NULL); switch (error) { case -ENOENT: error = 0; @@ -588,8 +647,7 @@ *gid = current->fsgid; } -static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, - u64 *generation) +static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); int error; @@ -605,7 +663,7 @@ if (error) goto out_ipreserv; - inum->no_addr = gfs2_alloc_di(dip, generation); + *no_addr = gfs2_alloc_di(dip, generation); gfs2_trans_end(sdp); @@ -635,6 +693,7 @@ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_dinode *di; struct buffer_head *dibh; + struct timespec tv = CURRENT_TIME; dibh = gfs2_meta_new(gl, inum->no_addr); gfs2_trans_add_bh(gl, dibh, 1); @@ -650,7 +709,7 @@ di->di_nlink = 0; di->di_size = 0; di->di_blocks = cpu_to_be64(1); - di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); + di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); di->di_major = cpu_to_be32(MAJOR(dev)); di->di_minor = cpu_to_be32(MINOR(dev)); di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); @@ -680,6 +739,9 @@ di->di_entries = 0; memset(&di->__pad4, 0, sizeof(di->__pad4)); di->di_eattr = 0; + di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); + di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); + di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); memset(&di->di_reserved, 0, sizeof(di->di_reserved)); brelse(dibh); @@ -749,7 +811,7 @@ goto fail_quota_locks; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 2 * RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) @@ -760,7 +822,7 @@ goto fail_quota_locks; } - error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); + error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); if (error) goto fail_end_trans; @@ -840,11 +902,11 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, unsigned int mode, dev_t dev) { - struct inode *inode; + struct inode *inode = NULL; struct gfs2_inode *dip = ghs->gh_gl->gl_object; struct inode *dir = &dip->i_inode; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); - struct gfs2_inum_host inum; + struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; int error; u64 generation; @@ -864,7 +926,7 @@ if (error) goto fail_gunlock; - error = alloc_dinode(dip, &inum, &generation); + error = alloc_dinode(dip, &inum.no_addr, &generation); if (error) goto fail_gunlock; @@ -877,34 +939,36 @@ if (error) goto fail_gunlock2; - inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode)); + inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), + inum.no_addr, + inum.no_formal_ino); if (IS_ERR(inode)) goto fail_gunlock2; error = gfs2_inode_refresh(GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = gfs2_acl_create(dip, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = gfs2_security_init(dip, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; error = link_dinode(dip, name, GFS2_I(inode)); if (error) - goto fail_iput; + goto fail_gunlock2; if (!inode) return ERR_PTR(-ENOMEM); return inode; -fail_iput: - iput(inode); fail_gunlock2: gfs2_glock_dq_uninit(ghs + 1); + if (inode) + iput(inode); fail_gunlock: gfs2_glock_dq(ghs); fail: @@ -976,10 +1040,8 @@ */ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, - struct gfs2_inode *ip) + const struct gfs2_inode *ip) { - struct gfs2_inum_host inum; - unsigned int type; int error; if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) @@ -997,18 +1059,10 @@ if (error) return error; - error = gfs2_dir_search(&dip->i_inode, name, &inum, &type); + error = gfs2_dir_check(&dip->i_inode, name, ip); if (error) return error; - if (!gfs2_inum_equal(&inum, &ip->i_num)) - return -ENOENT; - - if (IF2DT(ip->i_inode.i_mode) != type) { - gfs2_consist_inode(dip); - return -EIO; - } - return 0; } @@ -1132,10 +1186,11 @@ struct gfs2_glock *gl = gh->gh_gl; struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_inode *ip = gl->gl_object; - s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum); + s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); unsigned int state; int flags; int error; + struct timespec tv = CURRENT_TIME; if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || @@ -1153,8 +1208,7 @@ (sdp->sd_vfs->s_flags & MS_RDONLY)) return 0; - curtime = get_seconds(); - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { gfs2_glock_dq(gh); gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, gh); @@ -1165,8 +1219,8 @@ /* Verify that atime hasn't been updated while we were trying to get exclusive lock. */ - curtime = get_seconds(); - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { + tv = CURRENT_TIME; + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { struct buffer_head *dibh; struct gfs2_dinode *di; @@ -1180,11 +1234,12 @@ if (error) goto fail_end_trans; - ip->i_inode.i_atime.tv_sec = curtime; + ip->i_inode.i_atime = tv; gfs2_trans_add_bh(ip->i_gl, dibh, 1); di = (struct gfs2_dinode *)dibh->b_data; di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); + di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); brelse(dibh); gfs2_trans_end(sdp); @@ -1252,3 +1307,66 @@ return error; } +void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) +{ + const struct gfs2_dinode_host *di = &ip->i_di; + struct gfs2_dinode *str = buf; + + str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); + str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); + str->di_header.__pad0 = 0; + str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); + str->di_header.__pad1 = 0; + str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); + str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); + str->di_mode = cpu_to_be32(ip->i_inode.i_mode); + str->di_uid = cpu_to_be32(ip->i_inode.i_uid); + str->di_gid = cpu_to_be32(ip->i_inode.i_gid); + str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); + str->di_size = cpu_to_be64(di->di_size); + str->di_blocks = cpu_to_be64(di->di_blocks); + str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); + str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); + str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); + + str->di_goal_meta = cpu_to_be64(di->di_goal_meta); + str->di_goal_data = cpu_to_be64(di->di_goal_data); + str->di_generation = cpu_to_be64(di->di_generation); + + str->di_flags = cpu_to_be32(di->di_flags); + str->di_height = cpu_to_be16(di->di_height); + str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && + !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? + GFS2_FORMAT_DE : 0); + str->di_depth = cpu_to_be16(di->di_depth); + str->di_entries = cpu_to_be32(di->di_entries); + + str->di_eattr = cpu_to_be64(di->di_eattr); + str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); + str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); + str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); +} + +void gfs2_dinode_print(const struct gfs2_inode *ip) +{ + const struct gfs2_dinode_host *di = &ip->i_di; + + printk(KERN_INFO " no_formal_ino = %llu\n", + (unsigned long long)ip->i_no_formal_ino); + printk(KERN_INFO " no_addr = %llu\n", + (unsigned long long)ip->i_no_addr); + printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); + printk(KERN_INFO " di_blocks = %llu\n", + (unsigned long long)di->di_blocks); + printk(KERN_INFO " di_goal_meta = %llu\n", + (unsigned long long)di->di_goal_meta); + printk(KERN_INFO " di_goal_data = %llu\n", + (unsigned long long)di->di_goal_data); + printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); + printk(KERN_INFO " di_height = %u\n", di->di_height); + printk(KERN_INFO " di_depth = %u\n", di->di_depth); + printk(KERN_INFO " di_entries = %u\n", di->di_entries); + printk(KERN_INFO " di_eattr = %llu\n", + (unsigned long long)di->di_eattr); +} + --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/quota.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/quota.c @@ -66,6 +66,18 @@ #define QUOTA_USER 1 #define QUOTA_GROUP 0 +struct gfs2_quota_host { + u64 qu_limit; + u64 qu_warn; + s64 qu_value; +}; + +struct gfs2_quota_change_host { + u64 qc_change; + u32 qc_flags; /* GFS2_QCF_... */ + u32 qc_id; +}; + static u64 qd2offset(struct gfs2_quota_data *qd) { u64 offset; @@ -561,6 +573,25 @@ mutex_unlock(&sdp->sd_quota_mutex); } +static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) +{ + const struct gfs2_quota *str = buf; + + qu->qu_limit = be64_to_cpu(str->qu_limit); + qu->qu_warn = be64_to_cpu(str->qu_warn); + qu->qu_value = be64_to_cpu(str->qu_value); +} + +static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf) +{ + struct gfs2_quota *str = buf; + + str->qu_limit = cpu_to_be64(qu->qu_limit); + str->qu_warn = cpu_to_be64(qu->qu_warn); + str->qu_value = cpu_to_be64(qu->qu_value); + memset(&str->qu_reserved, 0, sizeof(str->qu_reserved)); +} + /** * gfs2_adjust_quota * @@ -573,12 +604,13 @@ struct inode *inode = &ip->i_inode; struct address_space *mapping = inode->i_mapping; unsigned long index = loc >> PAGE_CACHE_SHIFT; - unsigned offset = loc & (PAGE_CACHE_SHIFT - 1); + unsigned offset = loc & (PAGE_CACHE_SIZE - 1); unsigned blocksize, iblock, pos; struct buffer_head *bh; struct page *page; void *kaddr; - __be64 *ptr; + char *ptr; + struct gfs2_quota_host qp; s64 value; int err = -EIO; @@ -620,13 +652,17 @@ kaddr = kmap_atomic(page, KM_USER0); ptr = kaddr + offset; - value = (s64)be64_to_cpu(*ptr) + change; - *ptr = cpu_to_be64(value); + gfs2_quota_in(&qp, ptr); + qp.qu_value += change; + value = qp.qu_value; + gfs2_quota_out(&qp, ptr); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); err = 0; qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC); qd->qd_qb.qb_value = cpu_to_be64(value); + ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC); + ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value); unlock: unlock_page(page); page_cache_release(page); @@ -689,7 +725,7 @@ goto out_alloc; error = gfs2_trans_begin(sdp, - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + num_qd * data_blocks + nalloc * ind_blocks + RES_DINODE + num_qd + @@ -709,7 +745,7 @@ offset = qd2offset(qd); error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, (struct gfs2_quota_data *) - qd->qd_gl->gl_lvb); + qd); if (error) goto out_end_trans; @@ -1050,6 +1086,15 @@ return error; } +static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) +{ + const struct gfs2_quota_change *str = buf; + + qc->qc_change = be64_to_cpu(str->qc_change); + qc->qc_flags = be32_to_cpu(str->qc_flags); + qc->qc_id = be32_to_cpu(str->qc_id); +} + int gfs2_quota_init(struct gfs2_sbd *sdp) { struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/Makefile +++ linux-source-2.6.22-2.6.22/fs/gfs2/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_GFS2_FS) += gfs2.o gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ - mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ + mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ recovery.o rgrp.o super.o sys.o trans.o util.o --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_dentry.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_dentry.c @@ -21,6 +21,7 @@ #include "glock.h" #include "ops_dentry.h" #include "util.h" +#include "inode.h" /** * gfs2_drevalidate - Check directory lookup consistency @@ -40,14 +41,15 @@ struct gfs2_inode *dip = GFS2_I(parent->d_inode); struct inode *inode = dentry->d_inode; struct gfs2_holder d_gh; - struct gfs2_inode *ip; - struct gfs2_inum_host inum; - unsigned int type; + struct gfs2_inode *ip = NULL; int error; int had_lock=0; - if (inode && is_bad_inode(inode)) - goto invalid; + if (inode) { + if (is_bad_inode(inode)) + goto invalid; + ip = GFS2_I(inode); + } if (sdp->sd_args.ar_localcaching) goto valid; @@ -59,7 +61,7 @@ goto fail; } - error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type); + error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip); switch (error) { case 0: if (!inode) @@ -73,16 +75,6 @@ goto fail_gunlock; } - ip = GFS2_I(inode); - - if (!gfs2_inum_equal(&ip->i_num, &inum)) - goto invalid_gunlock; - - if (IF2DT(ip->i_inode.i_mode) != type) { - gfs2_consist_inode(dip); - goto fail_gunlock; - } - valid_gunlock: if (!had_lock) gfs2_glock_dq_uninit(&d_gh); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/rgrp.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/rgrp.h @@ -65,5 +65,6 @@ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, int flags); void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); +u64 gfs2_ri_total(struct gfs2_sbd *sdp); #endif /* __RGRP_DOT_H__ */ --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/glock.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/glock.c @@ -422,11 +422,11 @@ static void gfs2_holder_wake(struct gfs2_holder *gh) { clear_bit(HIF_WAIT, &gh->gh_iflags); - smp_mb(); + smp_mb__after_clear_bit(); wake_up_bit(&gh->gh_iflags, HIF_WAIT); } -static int holder_wait(void *word) +static int just_schedule(void *word) { schedule(); return 0; @@ -435,7 +435,20 @@ static void wait_on_holder(struct gfs2_holder *gh) { might_sleep(); - wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE); + wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); +} + +static void gfs2_demote_wake(struct gfs2_glock *gl) +{ + clear_bit(GLF_DEMOTE, &gl->gl_flags); + smp_mb__after_clear_bit(); + wake_up_bit(&gl->gl_flags, GLF_DEMOTE); +} + +static void wait_on_demote(struct gfs2_glock *gl) +{ + might_sleep(); + wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); } /** @@ -528,7 +541,7 @@ if (gl->gl_state == gl->gl_demote_state || gl->gl_state == LM_ST_UNLOCKED) { - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); return 0; } set_bit(GLF_LOCK, &gl->gl_flags); @@ -666,12 +679,22 @@ * practise: LM_ST_SHARED and LM_ST_UNLOCKED */ -static void handle_callback(struct gfs2_glock *gl, unsigned int state) +static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote) { spin_lock(&gl->gl_spin); if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { gl->gl_demote_state = state; gl->gl_demote_time = jiffies; + if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && + gl->gl_object) { + struct inode *inode = igrab(gl->gl_object); + spin_unlock(&gl->gl_spin); + if (inode) { + d_prune_aliases(inode); + iput(inode); + } + return; + } } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { gl->gl_demote_state = state; } @@ -740,7 +763,7 @@ if (ret & LM_OUT_CANCELED) op_done = 0; else - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); } else { spin_lock(&gl->gl_spin); list_del_init(&gh->gh_list); @@ -848,7 +871,7 @@ gfs2_assert_warn(sdp, !ret); state_change(gl, LM_ST_UNLOCKED); - clear_bit(GLF_DEMOTE, &gl->gl_flags); + gfs2_demote_wake(gl); if (glops->go_inval) glops->go_inval(gl, DIO_METADATA); @@ -1174,7 +1197,7 @@ const struct gfs2_glock_operations *glops = gl->gl_ops; if (gh->gh_flags & GL_NOCACHE) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_lock(gl); @@ -1196,6 +1219,13 @@ spin_unlock(&gl->gl_spin); } +void gfs2_glock_dq_wait(struct gfs2_holder *gh) +{ + struct gfs2_glock *gl = gh->gh_gl; + gfs2_glock_dq(gh); + wait_on_demote(gl); +} + /** * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it * @gh: the holder structure @@ -1297,10 +1327,6 @@ * @num_gh: the number of structures * @ghs: an array of struct gfs2_holder structures * - * Figure out how big an impact this function has. Either: - * 1) Replace this code with code that calls gfs2_glock_prefetch() - * 2) Forget async stuff and just call nq_m_sync() - * 3) Leave it like it is * * Returns: 0 on success (all glocks acquired), * errno on failure (no glocks acquired) @@ -1308,62 +1334,28 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) { - int *e; - unsigned int x; - int borked = 0, serious = 0; + struct gfs2_holder *tmp[4]; + struct gfs2_holder **pph = tmp; int error = 0; - if (!num_gh) + switch(num_gh) { + case 0: return 0; - - if (num_gh == 1) { + case 1: ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); return gfs2_glock_nq(ghs); - } - - e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); - if (!e) - return -ENOMEM; - - for (x = 0; x < num_gh; x++) { - ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; - error = gfs2_glock_nq(&ghs[x]); - if (error) { - borked = 1; - serious = error; - num_gh = x; + default: + if (num_gh <= 4) break; - } + pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS); + if (!pph) + return -ENOMEM; } - for (x = 0; x < num_gh; x++) { - error = e[x] = glock_wait_internal(&ghs[x]); - if (error) { - borked = 1; - if (error != GLR_TRYFAILED && error != GLR_CANCELED) - serious = error; - } - } - - if (!borked) { - kfree(e); - return 0; - } - - for (x = 0; x < num_gh; x++) - if (!e[x]) - gfs2_glock_dq(&ghs[x]); - - if (serious) - error = serious; - else { - for (x = 0; x < num_gh; x++) - gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, - &ghs[x]); - error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e); - } + error = nq_m_sync(num_gh, ghs, pph); - kfree(e); + if (pph != tmp) + kfree(pph); return error; } @@ -1456,7 +1448,7 @@ if (!gl) return; - handle_callback(gl, state); + handle_callback(gl, state, 1); spin_lock(&gl->gl_spin); run_queue(gl); @@ -1596,7 +1588,7 @@ if (gfs2_glmutex_trylock(gl)) { if (list_empty(&gl->gl_holders) && gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_unlock(gl); } @@ -1709,7 +1701,7 @@ if (gfs2_glmutex_trylock(gl)) { if (list_empty(&gl->gl_holders) && gl->gl_state != LM_ST_UNLOCKED) - handle_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED, 0); gfs2_glmutex_unlock(gl); } } @@ -1823,7 +1815,8 @@ print_dbg(gi, " Inode:\n"); print_dbg(gi, " num = %llu/%llu\n", - ip->i_num.no_formal_ino, ip->i_num.no_addr); + (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr); print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); print_dbg(gi, " i_flags ="); for (x = 0; x < 32; x++) @@ -1909,8 +1902,8 @@ } if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", - gl->gl_demote_state, - (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ)); + gl->gl_demote_state, (unsigned long long) + (jiffies - gl->gl_demote_time)*(1000000/HZ)); } if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { if (!test_bit(GLF_LOCK, &gl->gl_flags) && --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/super.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/super.h @@ -16,7 +16,7 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); -struct page *gfs2_read_super(struct super_block *sb, sector_t sector); +int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector); static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) { --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_vm.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_vm.c @@ -66,7 +66,7 @@ if (error) goto out_gunlock_q; - error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + + error = gfs2_trans_begin(sdp, al->al_rgd->rd_length + ind_blocks + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_address.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_address.h @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/log.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/log.c @@ -83,6 +83,11 @@ gfs2_assert(sdp, bd->bd_ail == ai); + if (!bh){ + list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); + continue; + } + if (!buffer_busy(bh)) { if (!buffer_uptodate(bh)) { gfs2_log_unlock(sdp); @@ -125,6 +130,11 @@ bd_ail_st_list) { bh = bd->bd_bh; + if (!bh){ + list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); + continue; + } + gfs2_assert(sdp, bd->bd_ail == ai); if (buffer_busy(bh)) { @@ -227,7 +237,10 @@ list_del(&bd->bd_ail_st_list); list_del(&bd->bd_ail_gl_list); atomic_dec(&bd->bd_gl->gl_ail_count); - brelse(bd->bd_bh); + if (bd->bd_bh) + brelse(bd->bd_bh); + else + kmem_cache_free(gfs2_bufdata_cachep, bd); } } @@ -262,8 +275,8 @@ * @sdp: The GFS2 superblock * @blks: The number of blocks to reserve * - * Note that we never give out the last 6 blocks of the journal. Thats - * due to the fact that there is are a small number of header blocks + * Note that we never give out the last few blocks of the journal. Thats + * due to the fact that there is a small number of header blocks * associated with each log flush. The exact number can't be known until * flush time, so we ensure that we have just enough free blocks at all * times to avoid running out during a log flush. @@ -274,6 +287,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) { unsigned int try = 0; + unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); if (gfs2_assert_warn(sdp, blks) || gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) @@ -281,7 +295,7 @@ mutex_lock(&sdp->sd_log_reserve_mutex); gfs2_log_lock(sdp); - while(sdp->sd_log_blks_free <= (blks + 6)) { + while(sdp->sd_log_blks_free <= (blks + reserved_blks)) { gfs2_log_unlock(sdp); gfs2_ail1_empty(sdp, 0); gfs2_log_flush(sdp, NULL); @@ -357,6 +371,58 @@ return dist; } +/** + * calc_reserved - Calculate the number of blocks to reserve when + * refunding a transaction's unused buffers. + * @sdp: The GFS2 superblock + * + * This is complex. We need to reserve room for all our currently used + * metadata buffers (e.g. normal file I/O rewriting file time stamps) and + * all our journaled data buffers for journaled files (e.g. files in the + * meta_fs like rindex, or files for which chattr +j was done.) + * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush + * will count it as free space (sd_log_blks_free) and corruption will follow. + * + * We can have metadata bufs and jdata bufs in the same journal. So each + * type gets its own log header, for which we need to reserve a block. + * In fact, each type has the potential for needing more than one header + * in cases where we have more buffers than will fit on a journal page. + * Metadata journal entries take up half the space of journaled buffer entries. + * Thus, metadata entries have buf_limit (502) and journaled buffers have + * databuf_limit (251) before they cause a wrap around. + * + * Also, we need to reserve blocks for revoke journal entries and one for an + * overall header for the lot. + * + * Returns: the number of blocks reserved + */ +static unsigned int calc_reserved(struct gfs2_sbd *sdp) +{ + unsigned int reserved = 0; + unsigned int mbuf_limit, metabufhdrs_needed; + unsigned int dbuf_limit, databufhdrs_needed; + unsigned int revokes = 0; + + mbuf_limit = buf_limit(sdp); + metabufhdrs_needed = (sdp->sd_log_commited_buf + + (mbuf_limit - 1)) / mbuf_limit; + dbuf_limit = databuf_limit(sdp); + databufhdrs_needed = (sdp->sd_log_commited_databuf + + (dbuf_limit - 1)) / dbuf_limit; + + if (sdp->sd_log_commited_revoke) + revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, + sizeof(u64)); + + reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + + sdp->sd_log_commited_databuf + databufhdrs_needed + + revokes; + /* One for the overall header */ + if (reserved) + reserved++; + return reserved; +} + static unsigned int current_tail(struct gfs2_sbd *sdp) { struct gfs2_ail *ai; @@ -447,14 +513,14 @@ return bh; } -static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) +static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) { unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); ail2_empty(sdp, new_tail); gfs2_log_lock(sdp); - sdp->sd_log_blks_free += dist - (pull ? 1 : 0); + sdp->sd_log_blks_free += dist; gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); gfs2_log_unlock(sdp); @@ -504,7 +570,7 @@ brelse(bh); if (sdp->sd_log_tail != tail) - log_pull_tail(sdp, tail, pull); + log_pull_tail(sdp, tail); else gfs2_assert_withdraw(sdp, !pull); @@ -565,7 +631,10 @@ INIT_LIST_HEAD(&ai->ai_ail1_list); INIT_LIST_HEAD(&ai->ai_ail2_list); - gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf == sdp->sd_log_commited_buf); + gfs2_assert_withdraw(sdp, + sdp->sd_log_num_buf + sdp->sd_log_num_jdata == + sdp->sd_log_commited_buf + + sdp->sd_log_commited_databuf); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); @@ -576,16 +645,19 @@ lops_before_commit(sdp); if (!list_empty(&sdp->sd_log_flush_list)) log_flush_commit(sdp); - else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) + else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ + gfs2_log_lock(sdp); + sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ + gfs2_log_unlock(sdp); log_write_header(sdp, 0, PULL); + } lops_after_commit(sdp, ai); gfs2_log_lock(sdp); sdp->sd_log_head = sdp->sd_log_flush_head; - sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs; sdp->sd_log_blks_reserved = 0; sdp->sd_log_commited_buf = 0; - sdp->sd_log_num_hdrs = 0; + sdp->sd_log_commited_databuf = 0; sdp->sd_log_commited_revoke = 0; if (!list_empty(&ai->ai_ail1_list)) { @@ -602,32 +674,26 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) { - unsigned int reserved = 0; + unsigned int reserved; unsigned int old; gfs2_log_lock(sdp); sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; - gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); + sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - + tr->tr_num_databuf_rm; + gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || + (((int)sdp->sd_log_commited_databuf) >= 0)); sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); - - if (sdp->sd_log_commited_buf) - reserved += sdp->sd_log_commited_buf; - if (sdp->sd_log_commited_revoke) - reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, - sizeof(u64)); - if (reserved) - reserved++; - + reserved = calc_reserved(sdp); old = sdp->sd_log_blks_free; sdp->sd_log_blks_free += tr->tr_reserved - (reserved - sdp->sd_log_blks_reserved); gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); - gfs2_assert_withdraw(sdp, - sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + - sdp->sd_log_num_hdrs); + gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= + sdp->sd_jdesc->jd_blocks); sdp->sd_log_blks_reserved = reserved; @@ -673,13 +739,13 @@ gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); - gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs); gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); sdp->sd_log_flush_head = sdp->sd_log_head; sdp->sd_log_flush_wrapped = 0; - log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); + log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, + (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_fstype.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_fstype.c @@ -27,7 +27,6 @@ #include "inode.h" #include "lm.h" #include "mount.h" -#include "ops_export.h" #include "ops_fstype.h" #include "ops_super.h" #include "recovery.h" @@ -105,6 +104,7 @@ sb->s_magic = GFS2_MAGIC; sb->s_op = &gfs2_super_ops; sb->s_export_op = &gfs2_export_ops; + sb->s_time_gran = 1; sb->s_maxbytes = MAX_LFS_FILESIZE; if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) @@ -116,7 +116,6 @@ static int init_names(struct gfs2_sbd *sdp, int silent) { - struct page *page; char *proto, *table; int error = 0; @@ -126,14 +125,9 @@ /* Try to autodetect */ if (!proto[0] || !table[0]) { - struct gfs2_sb *sb; - page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - if (!page) - return -ENOBUFS; - sb = kmap(page); - gfs2_sb_in(&sdp->sd_sb, sb); - kunmap(page); - __free_page(page); + error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + if (error) + return error; error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); if (error) @@ -151,6 +145,9 @@ snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); + while ((table = strchr(sdp->sd_table_name, '/'))) + *table = '_'; + out: return error; } @@ -236,17 +233,17 @@ return error; } -static struct inode *gfs2_lookup_root(struct super_block *sb, - struct gfs2_inum_host *inum) +static inline struct inode *gfs2_lookup_root(struct super_block *sb, + u64 no_addr) { - return gfs2_inode_lookup(sb, inum, DT_DIR); + return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); } static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) { struct super_block *sb = sdp->sd_vfs; struct gfs2_holder sb_gh; - struct gfs2_inum_host *inum; + u64 no_addr; struct inode *inode; int error = 0; @@ -289,10 +286,10 @@ sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); /* Get the root inode */ - inum = &sdp->sd_sb.sb_root_dir; + no_addr = sdp->sd_sb.sb_root_dir.no_addr; if (sb->s_type == &gfs2meta_fs_type) - inum = &sdp->sd_sb.sb_master_dir; - inode = gfs2_lookup_root(sb, inum); + no_addr = sdp->sd_sb.sb_master_dir.no_addr; + inode = gfs2_lookup_root(sb, no_addr); if (IS_ERR(inode)) { error = PTR_ERR(inode); fs_err(sdp, "can't read in root inode: %d\n", error); @@ -449,7 +446,7 @@ if (undo) goto fail_qinode; - inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir); + inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr); if (IS_ERR(inode)) { error = PTR_ERR(inode); fs_err(sdp, "can't read in master directory: %d\n", error); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking/dlm/thread.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking/dlm/thread.c @@ -44,6 +44,13 @@ ls->fscb(ls->sdp, cb, &lp->lockname); } +static void wake_up_ast(struct gdlm_lock *lp) +{ + clear_bit(LFL_AST_WAIT, &lp->flags); + smp_mb__after_clear_bit(); + wake_up_bit(&lp->flags, LFL_AST_WAIT); +} + static void process_complete(struct gdlm_lock *lp) { struct gdlm_ls *ls = lp->ls; @@ -136,7 +143,7 @@ */ if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { - complete(&lp->ast_wait); + wake_up_ast(lp); return; } @@ -214,7 +221,7 @@ if (test_bit(LFL_INLOCK, &lp->flags)) { clear_bit(LFL_NOBLOCK, &lp->flags); lp->cur = lp->req; - complete(&lp->ast_wait); + wake_up_ast(lp); return; } --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking/dlm/mount.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking/dlm/mount.c @@ -147,7 +147,7 @@ error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), &ls->dlm_lockspace, - nodir ? DLM_LSFL_NODIR : 0, + DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), GDLM_LVB_SIZE); if (error) { log_error("dlm_new_lockspace error %d", error); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking/dlm/lock.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking/dlm/lock.c @@ -174,7 +174,6 @@ lp->cur = DLM_LOCK_IV; lp->lvb = NULL; lp->hold_null = NULL; - init_completion(&lp->ast_wait); INIT_LIST_HEAD(&lp->clist); INIT_LIST_HEAD(&lp->blist); INIT_LIST_HEAD(&lp->delay_list); @@ -399,6 +398,12 @@ lp->lksb.sb_lvbptr = NULL; } +static int gdlm_ast_wait(void *word) +{ + schedule(); + return 0; +} + /* This can do a synchronous dlm request (requiring a lock_dlm thread to get the completion) because gfs won't call hold_lvb() during a callback (from the context of a lock_dlm thread). */ @@ -424,10 +429,10 @@ lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; set_bit(LFL_NOBAST, &lpn->flags); set_bit(LFL_INLOCK, &lpn->flags); + set_bit(LFL_AST_WAIT, &lpn->flags); - init_completion(&lpn->ast_wait); gdlm_do_lock(lpn); - wait_for_completion(&lpn->ast_wait); + wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE); error = lpn->lksb.sb_status; if (error) { printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking/dlm/plock.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking/dlm/plock.c @@ -242,7 +242,7 @@ op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); @@ -254,16 +254,20 @@ } spin_unlock(&ops_lock); + /* info.rv from userspace is 1 for conflict, 0 for no-conflict, + -ENOENT if there are no locks on the file */ + rv = op->info.rv; fl->fl_type = F_UNLCK; if (rv == -ENOENT) rv = 0; - else if (rv == 0 && op->info.pid != fl->fl_pid) { + else if (rv > 0) { fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; fl->fl_pid = op->info.pid; fl->fl_start = op->info.start; fl->fl_end = op->info.end; + rv = 0; } kfree(op); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/locking/dlm/lock_dlm.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/locking/dlm/lock_dlm.h @@ -101,6 +101,7 @@ LFL_NOBAST = 10, LFL_HEADQUE = 11, LFL_UNLOCK_DELETE = 12, + LFL_AST_WAIT = 13, }; struct gdlm_lock { @@ -117,7 +118,6 @@ unsigned long flags; /* lock_dlm flags LFL_ */ int bast_mode; /* protected by async_lock */ - struct completion ast_wait; struct list_head clist; /* complete */ struct list_head blist; /* blocking */ --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/meta_io.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/meta_io.h @@ -63,7 +63,7 @@ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, struct buffer_head **bhp) { - return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp); + return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp); } struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_super.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_super.c @@ -326,8 +326,10 @@ gfs2_glock_schedule_for_reclaim(ip->i_gl); gfs2_glock_put(ip->i_gl); ip->i_gl = NULL; - if (ip->i_iopen_gh.gh_gl) + if (ip->i_iopen_gh.gh_gl) { + ip->i_iopen_gh.gh_gl->gl_object = NULL; gfs2_glock_dq_uninit(&ip->i_iopen_gh); + } } } @@ -422,13 +424,13 @@ if (!inode->i_private) goto out; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); if (unlikely(error)) { gfs2_glock_dq_uninit(&ip->i_iopen_gh); goto out; } - gfs2_glock_dq(&ip->i_iopen_gh); + gfs2_glock_dq_wait(&ip->i_iopen_gh); gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); error = gfs2_glock_nq(&ip->i_iopen_gh); if (error) --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/mount.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/mount.c @@ -82,20 +82,19 @@ char *options, *o, *v; int error = 0; - if (!remount) { - /* If someone preloaded options, use those instead */ - spin_lock(&gfs2_sys_margs_lock); - if (gfs2_sys_margs) { - data = gfs2_sys_margs; - gfs2_sys_margs = NULL; - } - spin_unlock(&gfs2_sys_margs_lock); - - /* Set some defaults */ - args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; - args->ar_quota = GFS2_QUOTA_DEFAULT; - args->ar_data = GFS2_DATA_DEFAULT; + /* If someone preloaded options, use those instead */ + spin_lock(&gfs2_sys_margs_lock); + if (!remount && gfs2_sys_margs) { + data = gfs2_sys_margs; + gfs2_sys_margs = NULL; } + spin_unlock(&gfs2_sys_margs_lock); + + /* Set some defaults */ + memset(args, 0, sizeof(struct gfs2_args)); + args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; + args->ar_quota = GFS2_QUOTA_DEFAULT; + args->ar_data = GFS2_DATA_DEFAULT; /* Split the options into tokens with the "," character and process them */ --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/glock.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/glock.h @@ -87,6 +87,7 @@ int gfs2_glock_poll(struct gfs2_holder *gh); int gfs2_glock_wait(struct gfs2_holder *gh); void gfs2_glock_dq(struct gfs2_holder *gh); +void gfs2_glock_dq_wait(struct gfs2_holder *gh); void gfs2_glock_dq_uninit(struct gfs2_holder *gh); int gfs2_glock_nq_num(struct gfs2_sbd *sdp, --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_address.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_address.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -32,6 +32,7 @@ #include "trans.h" #include "rgrp.h" #include "ops_file.h" +#include "super.h" #include "util.h" #include "glops.h" @@ -49,6 +50,8 @@ end = start + bsize; if (end <= from || start >= to) continue; + if (gfs2_is_jdata(ip)) + set_buffer_uptodate(bh); gfs2_trans_add_bh(ip->i_gl, bh, 0); } } @@ -134,7 +137,9 @@ return 0; /* don't care */ } - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) { + if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) && + PageChecked(page)) { + ClearPageChecked(page); error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); if (error) goto out_ignore; @@ -203,11 +208,7 @@ * so we need to supply one here. It doesn't happen often. */ if (unlikely(page->index)) { - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr, 0, PAGE_CACHE_SIZE); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page); - SetPageUptodate(page); + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); return 0; } @@ -450,6 +451,31 @@ } /** + * adjust_fs_space - Adjusts the free space available due to gfs2_grow + * @inode: the rindex inode + */ +static void adjust_fs_space(struct inode *inode) +{ + struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; + u64 fs_total, new_free; + + /* Total up the file system space, according to the latest rindex. */ + fs_total = gfs2_ri_total(sdp); + + spin_lock(&sdp->sd_statfs_spin); + if (fs_total > (m_sc->sc_total + l_sc->sc_total)) + new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); + else + new_free = 0; + spin_unlock(&sdp->sd_statfs_spin); + fs_warn(sdp, "File system extended by %llu blocks.\n", + (unsigned long long)new_free); + gfs2_statfs_change(sdp, new_free, new_free, 0); +} + +/** * gfs2_commit_write - Commit write to a file * @file: The file to write to * @page: The page containing the data @@ -511,6 +537,9 @@ di->di_size = cpu_to_be64(inode->i_size); } + if (inode == sdp->sd_rindex) + adjust_fs_space(inode); + brelse(dibh); gfs2_trans_end(sdp); if (al->al_requested) { @@ -543,6 +572,23 @@ } /** + * gfs2_set_page_dirty - Page dirtying function + * @page: The page to dirty + * + * Returns: 1 if it dirtyed the page, or 0 otherwise + */ + +static int gfs2_set_page_dirty(struct page *page) +{ + struct gfs2_inode *ip = GFS2_I(page->mapping->host); + struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); + + if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + SetPageChecked(page); + return __set_page_dirty_buffers(page); +} + +/** * gfs2_bmap - Block map function * @mapping: Address space info * @lblock: The block to map @@ -578,6 +624,8 @@ if (bd) { bd->bd_bh = NULL; bh->b_private = NULL; + if (!bd->bd_ail && list_empty(&bd->bd_le.le_list)) + kmem_cache_free(gfs2_bufdata_cachep, bd); } gfs2_log_unlock(sdp); @@ -598,6 +646,8 @@ unsigned int curr_off = 0; BUG_ON(!PageLocked(page)); + if (offset == 0) + ClearPageChecked(page); if (!page_has_buffers(page)) return; @@ -728,8 +778,8 @@ return; fs_warn(sdp, "ip = %llu %llu\n", - (unsigned long long)ip->i_num.no_formal_ino, - (unsigned long long)ip->i_num.no_addr); + (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr); for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) fs_warn(sdp, "ip->i_cache[%u] = %s\n", @@ -810,6 +860,7 @@ .sync_page = block_sync_page, .prepare_write = gfs2_prepare_write, .commit_write = gfs2_commit_write, + .set_page_dirty = gfs2_set_page_dirty, .bmap = gfs2_bmap, .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage, --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/dir.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/dir.h @@ -16,15 +16,16 @@ struct gfs2_inode; struct gfs2_inum; -int gfs2_dir_search(struct inode *dir, const struct qstr *filename, - struct gfs2_inum_host *inum, unsigned int *type); +struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename); +int gfs2_dir_check(struct inode *dir, const struct qstr *filename, + const struct gfs2_inode *ip); int gfs2_dir_add(struct inode *inode, const struct qstr *filename, - const struct gfs2_inum_host *inum, unsigned int type); + const struct gfs2_inode *ip, unsigned int type); int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, filldir_t filldir); int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, - struct gfs2_inum_host *new_inum, unsigned int new_type); + const struct gfs2_inode *nip, unsigned int new_type); int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/lops.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/lops.h @@ -13,6 +13,13 @@ #include #include "incore.h" +#define BUF_OFFSET \ + ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \ + ~(sizeof(__be64) - 1)) +#define DATABUF_OFFSET \ + ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \ + ~(2 * sizeof(__be64) - 1)) + extern const struct gfs2_log_operations gfs2_glock_lops; extern const struct gfs2_log_operations gfs2_buf_lops; extern const struct gfs2_log_operations gfs2_revoke_lops; @@ -21,6 +28,22 @@ extern const struct gfs2_log_operations *gfs2_log_ops[]; +static inline unsigned int buf_limit(struct gfs2_sbd *sdp) +{ + unsigned int limit; + + limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64); + return limit; +} + +static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) +{ + unsigned int limit; + + limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64)); + return limit; +} + static inline void lops_init_le(struct gfs2_log_element *le, const struct gfs2_log_operations *lops) { --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/super.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/super.c @@ -95,8 +95,8 @@ { unsigned int x; - if (sb->sb_header.mh_magic != GFS2_MAGIC || - sb->sb_header.mh_type != GFS2_METATYPE_SB) { + if (sb->sb_magic != GFS2_MAGIC || + sb->sb_type != GFS2_METATYPE_SB) { if (!silent) printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); return -EINVAL; @@ -174,10 +174,31 @@ return 0; } +static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) +{ + const struct gfs2_sb *str = buf; + + sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); + sb->sb_type = be32_to_cpu(str->sb_header.mh_type); + sb->sb_format = be32_to_cpu(str->sb_header.mh_format); + sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); + sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); + sb->sb_bsize = be32_to_cpu(str->sb_bsize); + sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); + sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); + sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); + sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); + sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); + + memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); + memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); +} + /** * gfs2_read_super - Read the gfs2 super block from disk - * @sb: The VFS super block + * @sdp: The GFS2 super block * @sector: The location of the super block + * @error: The error code to return * * This uses the bio functions to read the super block from disk * because we want to be 100% sure that we never read cached data. @@ -189,17 +210,19 @@ * the master directory (contains pointers to journals etc) and the * root directory. * - * Returns: A page containing the sb or NULL + * Returns: 0 on success or error */ -struct page *gfs2_read_super(struct super_block *sb, sector_t sector) +int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) { + struct super_block *sb = sdp->sd_vfs; + struct gfs2_sb *p; struct page *page; struct bio *bio; page = alloc_page(GFP_KERNEL); if (unlikely(!page)) - return NULL; + return -ENOBUFS; ClearPageUptodate(page); ClearPageDirty(page); @@ -208,7 +231,7 @@ bio = bio_alloc(GFP_KERNEL, 1); if (unlikely(!bio)) { __free_page(page); - return NULL; + return -ENOBUFS; } bio->bi_sector = sector * (sb->s_blocksize >> 9); @@ -222,9 +245,13 @@ bio_put(bio); if (!PageUptodate(page)) { __free_page(page); - return NULL; + return -EIO; } - return page; + p = kmap(page); + gfs2_sb_in(&sdp->sd_sb, p); + kunmap(page); + __free_page(page); + return 0; } /** @@ -241,19 +268,13 @@ u32 tmp_blocks; unsigned int x; int error; - struct page *page; - char *sb; - page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); - if (!page) { + error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); + if (error) { if (!silent) fs_err(sdp, "can't read superblock\n"); - return -EIO; + return error; } - sb = kmap(page); - gfs2_sb_in(&sdp->sd_sb, sb); - kunmap(page); - __free_page(page); error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); if (error) @@ -360,7 +381,7 @@ name.len = sprintf(buf, "journal%u", sdp->sd_journals); name.hash = gfs2_disk_hash(name.name, name.len); - error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL); + error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); if (error == -ENOENT) { error = 0; break; @@ -593,6 +614,24 @@ return error; } +static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) +{ + const struct gfs2_statfs_change *str = buf; + + sc->sc_total = be64_to_cpu(str->sc_total); + sc->sc_free = be64_to_cpu(str->sc_free); + sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); +} + +static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) +{ + struct gfs2_statfs_change *str = buf; + + str->sc_total = cpu_to_be64(sc->sc_total); + str->sc_free = cpu_to_be64(sc->sc_free); + str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); +} + int gfs2_statfs_init(struct gfs2_sbd *sdp) { struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); @@ -772,7 +811,7 @@ struct gfs2_statfs_change_host *sc) { gfs2_rgrp_verify(rgd); - sc->sc_total += rgd->rd_ri.ri_data; + sc->sc_total += rgd->rd_data; sc->sc_free += rgd->rd_rg.rg_free; sc->sc_dinodes += rgd->rd_rg.rg_dinodes; return 0; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/glops.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/glops.c @@ -156,9 +156,9 @@ ip = NULL; if (test_bit(GLF_DIRTY, &gl->gl_flags)) { - gfs2_log_flush(gl->gl_sbd, gl); if (ip) filemap_fdatawrite(ip->i_inode.i_mapping); + gfs2_log_flush(gl->gl_sbd, gl); gfs2_meta_sync(gl); if (ip) { struct address_space *mapping = ip->i_inode.i_mapping; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/eattr.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/eattr.c @@ -254,7 +254,7 @@ if (error) return error; - error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE + + error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE + RES_EATTR + RES_STATFS + RES_QUOTA, blks); if (error) goto out_gunlock; @@ -300,7 +300,7 @@ error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -700,7 +700,7 @@ goto out_gunlock_q; error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), - blks + al->al_rgd->rd_ri.ri_length + + blks + al->al_rgd->rd_length + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) goto out_ipres; @@ -717,7 +717,7 @@ (er->er_mode & S_IFMT)); ip->i_inode.i_mode = er->er_mode; } - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -852,7 +852,7 @@ (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); ip->i_inode.i_mode = er->er_mode; } - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -1133,7 +1133,7 @@ error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -1352,7 +1352,7 @@ for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/bmap.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/bmap.c @@ -718,7 +718,7 @@ for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); @@ -772,7 +772,7 @@ gfs2_free_data(ip, bstart, blen); } - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, dibh->b_data); @@ -824,7 +824,7 @@ goto out_gunlock_q; error = gfs2_trans_begin(sdp, - sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + + sdp->sd_max_height + al->al_rgd->rd_length + RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) goto out_ipres; @@ -847,7 +847,7 @@ } ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; error = gfs2_meta_inode_buffer(ip, &dibh); if (error) @@ -885,7 +885,6 @@ unsigned blocksize, iblock, length, pos; struct buffer_head *bh; struct page *page; - void *kaddr; int err; page = grab_cache_page(mapping, index); @@ -928,15 +927,13 @@ /* Uhhuh. Read error. Complain and punt. */ if (!buffer_uptodate(bh)) goto unlock; + err = 0; } if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr + offset, 0, length); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); + zero_user_page(page, offset, length, KM_USER0); unlock: unlock_page(page); @@ -962,7 +959,7 @@ if (gfs2_is_stuffed(ip)) { ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); @@ -974,7 +971,7 @@ if (!error) { ip->i_di.di_size = size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -1044,10 +1041,10 @@ ip->i_di.di_height = 0; ip->i_di.di_goal_meta = ip->i_di.di_goal_data = - ip->i_num.no_addr; + ip->i_no_addr; gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); } - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; gfs2_trans_add_bh(ip->i_gl, dibh, 1); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/recovery.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/recovery.c @@ -116,6 +116,22 @@ } } +static int gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) +{ + const struct gfs2_log_header *str = buf; + + if (str->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || + str->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH)) + return 1; + + lh->lh_sequence = be64_to_cpu(str->lh_sequence); + lh->lh_flags = be32_to_cpu(str->lh_flags); + lh->lh_tail = be32_to_cpu(str->lh_tail); + lh->lh_blkno = be32_to_cpu(str->lh_blkno); + lh->lh_hash = be32_to_cpu(str->lh_hash); + return 0; +} + /** * get_log_header - read the log header for a given segment * @jd: the journal @@ -147,12 +163,10 @@ sizeof(u32)); hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); hash ^= (u32)~0; - gfs2_log_header_in(&lh, bh->b_data); + error = gfs2_log_header_in(&lh, bh->b_data); brelse(bh); - if (lh.lh_header.mh_magic != GFS2_MAGIC || - lh.lh_header.mh_type != GFS2_METATYPE_LH || - lh.lh_blkno != blk || lh.lh_hash != hash) + if (error || lh.lh_blkno != blk || lh.lh_hash != hash) return 1; *head = lh; --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_inode.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_inode.c @@ -157,7 +157,7 @@ if (error) goto out_gunlock; - error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL); + error = gfs2_dir_check(dir, &dentry->d_name, NULL); switch (error) { case -ENOENT: break; @@ -206,7 +206,7 @@ goto out_gunlock_q; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 2 * RES_DINODE + RES_STATFS + RES_QUOTA, 0); if (error) @@ -217,8 +217,7 @@ goto out_ipres; } - error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, - IF2DT(inode->i_mode)); + error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); if (error) goto out_end_trans; @@ -275,7 +274,7 @@ gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); @@ -420,7 +419,7 @@ dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); - gfs2_inum_out(&dip->i_num, &dent->de_inum); + gfs2_inum_out(dip, dent); dent->de_type = cpu_to_be16(DT_DIR); gfs2_dinode_out(ip, di); @@ -472,7 +471,7 @@ gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); - rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); + rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); error = gfs2_glock_nq_m(3, ghs); @@ -614,7 +613,7 @@ * this is the case of the target file already existing * so we unlink before doing the rename */ - nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr); + nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); if (nrgd) gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); } @@ -653,7 +652,7 @@ if (error) goto out_gunlock; - error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL); + error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); switch (error) { case -ENOENT: error = 0; @@ -712,7 +711,7 @@ goto out_gunlock_q; error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + - al->al_rgd->rd_ri.ri_length + + al->al_rgd->rd_length + 4 * RES_DINODE + 4 * RES_LEAF + RES_STATFS + RES_QUOTA + 4, 0); if (error) @@ -750,7 +749,7 @@ if (error) goto out_end_trans; - error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR); + error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); if (error) goto out_end_trans; } else { @@ -758,7 +757,7 @@ error = gfs2_meta_inode_buffer(ip, &dibh); if (error) goto out_end_trans; - ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -768,8 +767,7 @@ if (error) goto out_end_trans; - error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, - IF2DT(ip->i_inode.i_mode)); + error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); if (error) goto out_end_trans; @@ -905,8 +903,8 @@ } error = gfs2_truncatei(ip, attr->ia_size); - if (error) - return error; + if (error && (inode->i_size != ip->i_di.di_size)) + i_size_write(inode, ip->i_di.di_size); return error; } --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/inode.h +++ linux-source-2.6.22-2.6.22/fs/gfs2/inode.h @@ -10,17 +10,17 @@ #ifndef __INODE_DOT_H__ #define __INODE_DOT_H__ -static inline int gfs2_is_stuffed(struct gfs2_inode *ip) +static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) { return !ip->i_di.di_height; } -static inline int gfs2_is_jdata(struct gfs2_inode *ip) +static inline int gfs2_is_jdata(const struct gfs2_inode *ip) { return ip->i_di.di_flags & GFS2_DIF_JDATA; } -static inline int gfs2_is_dir(struct gfs2_inode *ip) +static inline int gfs2_is_dir(const struct gfs2_inode *ip) { return S_ISDIR(ip->i_inode.i_mode); } @@ -32,9 +32,25 @@ (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); } +static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, + u64 no_formal_ino) +{ + return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; +} + +static inline void gfs2_inum_out(const struct gfs2_inode *ip, + struct gfs2_dirent *dent) +{ + dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); + dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); +} + + void gfs2_inode_attr_in(struct gfs2_inode *ip); -struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); -struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); +void gfs2_set_iop(struct inode *inode); +struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, + u64 no_addr, u64 no_formal_ino); +struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); int gfs2_inode_refresh(struct gfs2_inode *ip); @@ -47,12 +63,14 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, struct gfs2_inode *ip); int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, - struct gfs2_inode *ip); + const struct gfs2_inode *ip); int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); int gfs2_glock_nq_atime(struct gfs2_holder *gh); int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); +void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); +void gfs2_dinode_print(const struct gfs2_inode *ip); #endif /* __INODE_DOT_H__ */ --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/dir.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/dir.c @@ -130,7 +130,7 @@ memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); if (ip->i_di.di_size < offset + size) ip->i_di.di_size = offset + size; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -228,7 +228,7 @@ if (ip->i_di.di_size < offset + copied) ip->i_di.di_size = offset + copied; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_dinode_out(ip, dibh->b_data); @@ -1456,7 +1456,7 @@ if (dip->i_di.di_entries != g.offset) { fs_warn(sdp, "Number of entries corrupt in dir %llu, " "ip->i_di.di_entries (%u) != g.offset (%u)\n", - (unsigned long long)dip->i_num.no_addr, + (unsigned long long)dip->i_no_addr, dip->i_di.di_entries, g.offset); error = -EIO; @@ -1488,24 +1488,55 @@ * Returns: errno */ -int gfs2_dir_search(struct inode *dir, const struct qstr *name, - struct gfs2_inum_host *inum, unsigned int *type) +struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) { struct buffer_head *bh; struct gfs2_dirent *dent; + struct inode *inode; + + dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); + if (dent) { + if (IS_ERR(dent)) + return ERR_PTR(PTR_ERR(dent)); + inode = gfs2_inode_lookup(dir->i_sb, + be16_to_cpu(dent->de_type), + be64_to_cpu(dent->de_inum.no_addr), + be64_to_cpu(dent->de_inum.no_formal_ino)); + brelse(bh); + return inode; + } + return ERR_PTR(-ENOENT); +} + +int gfs2_dir_check(struct inode *dir, const struct qstr *name, + const struct gfs2_inode *ip) +{ + struct buffer_head *bh; + struct gfs2_dirent *dent; + int ret = -ENOENT; dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); if (dent) { if (IS_ERR(dent)) return PTR_ERR(dent); - if (inum) - gfs2_inum_in(inum, (char *)&dent->de_inum); - if (type) - *type = be16_to_cpu(dent->de_type); + if (ip) { + if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr) + goto out; + if (be64_to_cpu(dent->de_inum.no_formal_ino) != + ip->i_no_formal_ino) + goto out; + if (unlikely(IF2DT(ip->i_inode.i_mode) != + be16_to_cpu(dent->de_type))) { + gfs2_consist_inode(GFS2_I(dir)); + ret = -EIO; + goto out; + } + } + ret = 0; +out: brelse(bh); - return 0; } - return -ENOENT; + return ret; } static int dir_new_leaf(struct inode *inode, const struct qstr *name) @@ -1565,7 +1596,7 @@ */ int gfs2_dir_add(struct inode *inode, const struct qstr *name, - const struct gfs2_inum_host *inum, unsigned type) + const struct gfs2_inode *nip, unsigned type) { struct gfs2_inode *ip = GFS2_I(inode); struct buffer_head *bh; @@ -1580,7 +1611,7 @@ if (IS_ERR(dent)) return PTR_ERR(dent); dent = gfs2_init_dirent(inode, dent, name, bh); - gfs2_inum_out(inum, (char *)&dent->de_inum); + gfs2_inum_out(nip, dent); dent->de_type = cpu_to_be16(type); if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { leaf = (struct gfs2_leaf *)bh->b_data; @@ -1592,7 +1623,7 @@ break; gfs2_trans_add_bh(ip->i_gl, bh, 1); ip->i_di.di_entries++; - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(ip, bh->b_data); brelse(bh); error = 0; @@ -1678,7 +1709,7 @@ gfs2_consist_inode(dip); gfs2_trans_add_bh(dip->i_gl, bh, 1); dip->i_di.di_entries--; - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(dip, bh->b_data); brelse(bh); mark_inode_dirty(&dip->i_inode); @@ -1700,7 +1731,7 @@ */ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, - struct gfs2_inum_host *inum, unsigned int new_type) + const struct gfs2_inode *nip, unsigned int new_type) { struct buffer_head *bh; struct gfs2_dirent *dent; @@ -1715,7 +1746,7 @@ return PTR_ERR(dent); gfs2_trans_add_bh(dip->i_gl, bh, 1); - gfs2_inum_out(inum, (char *)&dent->de_inum); + gfs2_inum_out(nip, dent); dent->de_type = cpu_to_be16(new_type); if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { @@ -1726,7 +1757,7 @@ gfs2_trans_add_bh(dip->i_gl, bh, 1); } - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; gfs2_dinode_out(dip, bh->b_data); brelse(bh); return 0; @@ -1867,7 +1898,7 @@ for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; rgd = rlist.rl_ghs[x].gh_gl->gl_object; - rg_blocks += rgd->rd_ri.ri_length; + rg_blocks += rgd->rd_length; } error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/ops_export.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/ops_export.c @@ -22,10 +22,13 @@ #include "glops.h" #include "inode.h" #include "ops_dentry.h" -#include "ops_export.h" +#include "ops_fstype.h" #include "rgrp.h" #include "util.h" +#define GFS2_SMALL_FH_SIZE 4 +#define GFS2_LARGE_FH_SIZE 8 + static struct dentry *gfs2_decode_fh(struct super_block *sb, __u32 *p, int fh_len, @@ -35,11 +38,8 @@ void *context) { __be32 *fh = (__force __be32 *)p; - struct gfs2_fh_obj fh_obj; - struct gfs2_inum_host *this, parent; + struct gfs2_inum_host inum, parent; - this = &fh_obj.this; - fh_obj.imode = DT_UNKNOWN; memset(&parent, 0, sizeof(struct gfs2_inum)); switch (fh_len) { @@ -48,18 +48,17 @@ parent.no_formal_ino |= be32_to_cpu(fh[5]); parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; parent.no_addr |= be32_to_cpu(fh[7]); - fh_obj.imode = be32_to_cpu(fh[8]); case GFS2_SMALL_FH_SIZE: - this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; - this->no_formal_ino |= be32_to_cpu(fh[1]); - this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; - this->no_addr |= be32_to_cpu(fh[3]); + inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; + inum.no_formal_ino |= be32_to_cpu(fh[1]); + inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; + inum.no_addr |= be32_to_cpu(fh[3]); break; default: return NULL; } - return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, + return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent, acceptable, context); } @@ -75,10 +74,10 @@ (connectable && *len < GFS2_LARGE_FH_SIZE)) return 255; - fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); - fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); - fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); - fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); + fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); + fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); + fh[2] = cpu_to_be32(ip->i_no_addr >> 32); + fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); *len = GFS2_SMALL_FH_SIZE; if (!connectable || inode == sb->s_root->d_inode) @@ -90,13 +89,10 @@ igrab(inode); spin_unlock(&dentry->d_lock); - fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); - fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); - fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); - fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); - - fh[8] = cpu_to_be32(inode->i_mode); - fh[9] = 0; /* pad to double word */ + fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); + fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); + fh[6] = cpu_to_be32(ip->i_no_addr >> 32); + fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); *len = GFS2_LARGE_FH_SIZE; iput(inode); @@ -144,7 +140,8 @@ ip = GFS2_I(inode); *name = 0; - gnfd.inum = ip->i_num; + gnfd.inum.no_addr = ip->i_no_addr; + gnfd.inum.no_formal_ino = ip->i_no_formal_ino; gnfd.name = name; error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); @@ -192,8 +189,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) { struct gfs2_sbd *sdp = sb->s_fs_info; - struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; - struct gfs2_inum_host *inum = &fh_obj->this; + struct gfs2_inum_host *inum = inum_obj; struct gfs2_holder i_gh, ri_gh, rgd_gh; struct gfs2_rgrpd *rgd; struct inode *inode; @@ -202,9 +198,9 @@ /* System files? */ - inode = gfs2_ilookup(sb, inum); + inode = gfs2_ilookup(sb, inum->no_addr); if (inode) { - if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { iput(inode); return ERR_PTR(-ESTALE); } @@ -236,7 +232,9 @@ gfs2_glock_dq_uninit(&rgd_gh); gfs2_glock_dq_uninit(&ri_gh); - inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, + inum->no_addr, + 0); if (!inode) goto fail; if (IS_ERR(inode)) { @@ -250,6 +248,15 @@ goto fail; } + /* Pick up the works we bypass in gfs2_inode_lookup */ + if (inode->i_state & I_NEW) + gfs2_set_iop(inode); + + if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { + iput(inode); + goto fail; + } + error = -EIO; if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { iput(inode); --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/util.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/util.c @@ -115,8 +115,8 @@ "GFS2: fsid=%s: inode = %llu %llu\n" "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", sdp->sd_fsname, - sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino, - (unsigned long long)ip->i_num.no_addr, + sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino, + (unsigned long long)ip->i_no_addr, sdp->sd_fsname, function, file, line); return rv; } @@ -137,7 +137,7 @@ "GFS2: fsid=%s: RG = %llu\n" "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", sdp->sd_fsname, - sdp->sd_fsname, (unsigned long long)rgd->rd_ri.ri_addr, + sdp->sd_fsname, (unsigned long long)rgd->rd_addr, sdp->sd_fsname, function, file, line); return rv; } --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/rgrp.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/rgrp.c @@ -1,6 +1,6 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -28,6 +28,7 @@ #include "ops_file.h" #include "util.h" #include "log.h" +#include "inode.h" #define BFITNOENT ((u32)~0) @@ -50,6 +51,9 @@ 1, 0, 0, 0 }; +static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, + unsigned char old_state, unsigned char new_state); + /** * gfs2_setbit - Set a bit in the bitmaps * @buffer: the buffer that holds the bitmaps @@ -204,7 +208,7 @@ { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_bitmap *bi = NULL; - u32 length = rgd->rd_ri.ri_length; + u32 length = rgd->rd_length; u32 count[4], tmp; int buf, x; @@ -227,7 +231,7 @@ return; } - tmp = rgd->rd_ri.ri_data - + tmp = rgd->rd_data - rgd->rd_rg.rg_free - rgd->rd_rg.rg_dinodes; if (count[1] + count[2] != tmp) { @@ -253,10 +257,10 @@ } -static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) +static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) { - u64 first = ri->ri_data0; - u64 last = first + ri->ri_data; + u64 first = rgd->rd_data0; + u64 last = first + rgd->rd_data; return first <= block && block < last; } @@ -275,7 +279,7 @@ spin_lock(&sdp->sd_rindex_spin); list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { - if (rgrp_contains_block(&rgd->rd_ri, blk)) { + if (rgrp_contains_block(rgd, blk)) { list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); spin_unlock(&sdp->sd_rindex_spin); return rgd; @@ -354,6 +358,15 @@ mutex_unlock(&sdp->sd_rindex_mutex); } +static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) +{ + printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); + printk(KERN_INFO " ri_length = %u\n", rgd->rd_length); + printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0); + printk(KERN_INFO " ri_data = %u\n", rgd->rd_data); + printk(KERN_INFO " ri_bitbytes = %u\n", rgd->rd_bitbytes); +} + /** * gfs2_compute_bitstructs - Compute the bitmap sizes * @rgd: The resource group descriptor @@ -367,7 +380,7 @@ { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_bitmap *bi; - u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ + u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */ u32 bytes_left, bytes; int x; @@ -378,7 +391,7 @@ if (!rgd->rd_bits) return -ENOMEM; - bytes_left = rgd->rd_ri.ri_bitbytes; + bytes_left = rgd->rd_bitbytes; for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; @@ -399,14 +412,14 @@ } else if (x + 1 == length) { bytes = bytes_left; bi->bi_offset = sizeof(struct gfs2_meta_header); - bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bi->bi_start = rgd->rd_bitbytes - bytes_left; bi->bi_len = bytes; /* other blocks */ } else { bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); bi->bi_offset = sizeof(struct gfs2_meta_header); - bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bi->bi_start = rgd->rd_bitbytes - bytes_left; bi->bi_len = bytes; } @@ -418,9 +431,9 @@ return -EIO; } bi = rgd->rd_bits + (length - 1); - if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) { + if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_data) { if (gfs2_consist_rgrpd(rgd)) { - gfs2_rindex_print(&rgd->rd_ri); + gfs2_rindex_print(rgd); fs_err(sdp, "start=%u len=%u offset=%u\n", bi->bi_start, bi->bi_len, bi->bi_offset); } @@ -431,9 +444,104 @@ } /** - * gfs2_ri_update - Pull in a new resource index from the disk + * gfs2_ri_total - Total up the file system space, according to the rindex. + * + */ +u64 gfs2_ri_total(struct gfs2_sbd *sdp) +{ + u64 total_data = 0; + struct inode *inode = sdp->sd_rindex; + struct gfs2_inode *ip = GFS2_I(inode); + char buf[sizeof(struct gfs2_rindex)]; + struct file_ra_state ra_state; + int error, rgrps; + + mutex_lock(&sdp->sd_rindex_mutex); + file_ra_state_init(&ra_state, inode->i_mapping); + for (rgrps = 0;; rgrps++) { + loff_t pos = rgrps * sizeof(struct gfs2_rindex); + + if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) + break; + error = gfs2_internal_read(ip, &ra_state, buf, &pos, + sizeof(struct gfs2_rindex)); + if (error != sizeof(struct gfs2_rindex)) + break; + total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data); + } + mutex_unlock(&sdp->sd_rindex_mutex); + return total_data; +} + +static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf) +{ + const struct gfs2_rindex *str = buf; + + rgd->rd_addr = be64_to_cpu(str->ri_addr); + rgd->rd_length = be32_to_cpu(str->ri_length); + rgd->rd_data0 = be64_to_cpu(str->ri_data0); + rgd->rd_data = be32_to_cpu(str->ri_data); + rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); +} + +/** + * read_rindex_entry - Pull in a new resource index entry from the disk * @gl: The glock covering the rindex inode * + * Returns: 0 on success, error code otherwise + */ + +static int read_rindex_entry(struct gfs2_inode *ip, + struct file_ra_state *ra_state) +{ + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); + char buf[sizeof(struct gfs2_rindex)]; + int error; + struct gfs2_rgrpd *rgd; + + error = gfs2_internal_read(ip, ra_state, buf, &pos, + sizeof(struct gfs2_rindex)); + if (!error) + return 0; + if (error != sizeof(struct gfs2_rindex)) { + if (error > 0) + error = -EIO; + return error; + } + + rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); + error = -ENOMEM; + if (!rgd) + return error; + + mutex_init(&rgd->rd_mutex); + lops_init_le(&rgd->rd_le, &gfs2_rg_lops); + rgd->rd_sbd = sdp; + + list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); + list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); + + gfs2_rindex_in(rgd, buf); + error = compute_bitstructs(rgd); + if (error) + return error; + + error = gfs2_glock_get(sdp, rgd->rd_addr, + &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); + if (error) + return error; + + rgd->rd_gl->gl_object = rgd; + rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + rgd->rd_flags |= GFS2_RDF_CHECK; + return error; +} + +/** + * gfs2_ri_update - Pull in a new resource index from the disk + * @ip: pointer to the rindex inode + * * Returns: 0 on successful update, error code otherwise */ @@ -441,13 +549,11 @@ { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct inode *inode = &ip->i_inode; - struct gfs2_rgrpd *rgd; - char buf[sizeof(struct gfs2_rindex)]; struct file_ra_state ra_state; - u64 junk = ip->i_di.di_size; + u64 rgrp_count = ip->i_di.di_size; int error; - if (do_div(junk, sizeof(struct gfs2_rindex))) { + if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { gfs2_consist_inode(ip); return -EIO; } @@ -455,50 +561,50 @@ clear_rgrpdi(sdp); file_ra_state_init(&ra_state, inode->i_mapping); - for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { - loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); - error = gfs2_internal_read(ip, &ra_state, buf, &pos, - sizeof(struct gfs2_rindex)); - if (!error) - break; - if (error != sizeof(struct gfs2_rindex)) { - if (error > 0) - error = -EIO; - goto fail; + for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) { + error = read_rindex_entry(ip, &ra_state); + if (error) { + clear_rgrpdi(sdp); + return error; } + } - rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); - error = -ENOMEM; - if (!rgd) - goto fail; - - mutex_init(&rgd->rd_mutex); - lops_init_le(&rgd->rd_le, &gfs2_rg_lops); - rgd->rd_sbd = sdp; - - list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); - list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); - - gfs2_rindex_in(&rgd->rd_ri, buf); - error = compute_bitstructs(rgd); - if (error) - goto fail; + sdp->sd_rindex_vn = ip->i_gl->gl_vn; + return 0; +} - error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, - &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); - if (error) - goto fail; +/** + * gfs2_ri_update_special - Pull in a new resource index from the disk + * + * This is a special version that's safe to call from gfs2_inplace_reserve_i. + * In this case we know that we don't have any resource groups in memory yet. + * + * @ip: pointer to the rindex inode + * + * Returns: 0 on successful update, error code otherwise + */ +static int gfs2_ri_update_special(struct gfs2_inode *ip) +{ + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + struct inode *inode = &ip->i_inode; + struct file_ra_state ra_state; + int error; - rgd->rd_gl->gl_object = rgd; - rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + file_ra_state_init(&ra_state, inode->i_mapping); + for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { + /* Ignore partials */ + if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > + ip->i_di.di_size) + break; + error = read_rindex_entry(ip, &ra_state); + if (error) { + clear_rgrpdi(sdp); + return error; + } } sdp->sd_rindex_vn = ip->i_gl->gl_vn; return 0; - -fail: - clear_rgrpdi(sdp); - return error; } /** @@ -543,6 +649,28 @@ return error; } +static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) +{ + const struct gfs2_rgrp *str = buf; + + rg->rg_flags = be32_to_cpu(str->rg_flags); + rg->rg_free = be32_to_cpu(str->rg_free); + rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); + rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); +} + +static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) +{ + struct gfs2_rgrp *str = buf; + + str->rg_flags = cpu_to_be32(rg->rg_flags); + str->rg_free = cpu_to_be32(rg->rg_free); + str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); + str->__pad = cpu_to_be32(0); + str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); + memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); +} + /** * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps * @rgd: the struct gfs2_rgrpd describing the RG to read in @@ -557,7 +685,7 @@ { struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_glock *gl = rgd->rd_gl; - unsigned int length = rgd->rd_ri.ri_length; + unsigned int length = rgd->rd_length; struct gfs2_bitmap *bi; unsigned int x, y; int error; @@ -575,7 +703,7 @@ for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; - error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh); + error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); if (error) goto fail; } @@ -637,7 +765,7 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; - int x, length = rgd->rd_ri.ri_length; + int x, length = rgd->rd_length; spin_lock(&sdp->sd_rindex_spin); gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); @@ -660,7 +788,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; - unsigned int length = rgd->rd_ri.ri_length; + unsigned int length = rgd->rd_length; unsigned int x; for (x = 0; x < length; x++) { @@ -722,6 +850,38 @@ } /** + * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes + * @rgd: The rgrp + * + * Returns: The inode, if one has been found + */ + +static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) +{ + struct inode *inode; + u32 goal = 0; + u64 no_addr; + + for(;;) { + goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, + GFS2_BLKST_UNLINKED); + if (goal == 0) + return 0; + no_addr = goal + rgd->rd_data0; + if (no_addr <= *last_unlinked) + continue; + *last_unlinked = no_addr; + inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, + no_addr, -1); + if (!IS_ERR(inode)) + return inode; + } + + rgd->rd_flags &= ~GFS2_RDF_CHECK; + return NULL; +} + +/** * recent_rgrp_first - get first RG from "recent" list * @sdp: The GFS2 superblock * @rglast: address of the rgrp used last @@ -743,7 +903,7 @@ goto first; list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { - if (rgd->rd_ri.ri_addr == rglast) + if (rgd->rd_addr == rglast) goto out; } @@ -882,8 +1042,9 @@ * Returns: errno */ -static int get_local_rgrp(struct gfs2_inode *ip) +static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) { + struct inode *inode = NULL; struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_rgrpd *rgd, *begin = NULL; struct gfs2_alloc *al = &ip->i_alloc; @@ -903,7 +1064,11 @@ case 0: if (try_rgrp_fit(rgd, al)) goto out; + if (rgd->rd_flags & GFS2_RDF_CHECK) + inode = try_rgrp_unlink(rgd, last_unlinked); gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (inode) + return inode; rgd = recent_rgrp_next(rgd, 1); break; @@ -912,7 +1077,7 @@ break; default: - return error; + return ERR_PTR(error); } } @@ -927,7 +1092,11 @@ case 0: if (try_rgrp_fit(rgd, al)) goto out; + if (rgd->rd_flags & GFS2_RDF_CHECK) + inode = try_rgrp_unlink(rgd, last_unlinked); gfs2_glock_dq_uninit(&al->al_rgd_gh); + if (inode) + return inode; break; case GLR_TRYFAILED: @@ -935,7 +1104,7 @@ break; default: - return error; + return ERR_PTR(error); } rgd = gfs2_rgrpd_get_next(rgd); @@ -944,7 +1113,7 @@ if (rgd == begin) { if (++loops >= 3) - return -ENOSPC; + return ERR_PTR(-ENOSPC); if (!skipped) loops++; flags = 0; @@ -954,7 +1123,7 @@ } out: - ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; + ip->i_last_rg_alloc = rgd->rd_addr; if (begin) { recent_rgrp_add(rgd); @@ -964,7 +1133,7 @@ forward_rgrp_set(sdp, rgd); } - return 0; + return NULL; } /** @@ -978,19 +1147,33 @@ { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = &ip->i_alloc; - int error; + struct inode *inode; + int error = 0; + u64 last_unlinked = 0; if (gfs2_assert_warn(sdp, al->al_requested)) return -EINVAL; - error = gfs2_rindex_hold(sdp, &al->al_ri_gh); +try_again: + /* We need to hold the rindex unless the inode we're using is + the rindex itself, in which case it's already held. */ + if (ip != GFS2_I(sdp->sd_rindex)) + error = gfs2_rindex_hold(sdp, &al->al_ri_gh); + else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ + error = gfs2_ri_update_special(ip); + if (error) return error; - error = get_local_rgrp(ip); - if (error) { - gfs2_glock_dq_uninit(&al->al_ri_gh); - return error; + inode = get_local_rgrp(ip, &last_unlinked); + if (inode) { + if (ip != GFS2_I(sdp->sd_rindex)) + gfs2_glock_dq_uninit(&al->al_ri_gh); + if (IS_ERR(inode)) + return PTR_ERR(inode); + iput(inode); + gfs2_log_flush(sdp, NULL); + goto try_again; } al->al_file = file; @@ -1019,7 +1202,8 @@ al->al_rgd = NULL; gfs2_glock_dq_uninit(&al->al_rgd_gh); - gfs2_glock_dq_uninit(&al->al_ri_gh); + if (ip != GFS2_I(sdp->sd_rindex)) + gfs2_glock_dq_uninit(&al->al_ri_gh); } /** @@ -1037,8 +1221,8 @@ unsigned int buf; unsigned char type; - length = rgd->rd_ri.ri_length; - rgrp_block = block - rgd->rd_ri.ri_data0; + length = rgd->rd_length; + rgrp_block = block - rgd->rd_data0; for (buf = 0; buf < length; buf++) { bi = rgd->rd_bits + buf; @@ -1077,10 +1261,10 @@ */ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, - unsigned char old_state, unsigned char new_state) + unsigned char old_state, unsigned char new_state) { struct gfs2_bitmap *bi = NULL; - u32 length = rgd->rd_ri.ri_length; + u32 length = rgd->rd_length; u32 blk = 0; unsigned int buf, x; @@ -1118,17 +1302,18 @@ goal = 0; } - if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) - blk = 0; + if (old_state != new_state) { + gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT); - gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); - gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, - bi->bi_len, blk, new_state); - if (bi->bi_clone) - gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, + gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); + gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, bi->bi_len, blk, new_state); + if (bi->bi_clone) + gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, + bi->bi_len, blk, new_state); + } - return bi->bi_start * GFS2_NBBY + blk; + return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk; } /** @@ -1156,9 +1341,9 @@ return NULL; } - length = rgd->rd_ri.ri_length; + length = rgd->rd_length; - rgrp_blk = bstart - rgd->rd_ri.ri_data0; + rgrp_blk = bstart - rgd->rd_data0; while (blen--) { for (buf = 0; buf < length; buf++) { @@ -1202,15 +1387,15 @@ u32 goal, blk; u64 block; - if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data)) - goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0; + if (rgrp_contains_block(rgd, ip->i_di.di_goal_data)) + goal = ip->i_di.di_goal_data - rgd->rd_data0; else goal = rgd->rd_last_alloc_data; blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_data = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; ip->i_di.di_goal_data = block; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); @@ -1246,15 +1431,15 @@ u32 goal, blk; u64 block; - if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta)) - goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0; + if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta)) + goal = ip->i_di.di_goal_meta - rgd->rd_data0; else goal = rgd->rd_last_alloc_meta; blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); rgd->rd_last_alloc_meta = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; ip->i_di.di_goal_meta = block; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); @@ -1296,7 +1481,7 @@ rgd->rd_last_alloc_meta = blk; - block = rgd->rd_ri.ri_data0 + blk; + block = rgd->rd_data0 + blk; gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); rgd->rd_rg.rg_free--; @@ -1379,7 +1564,7 @@ struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_rgrpd *rgd; - u64 blkno = ip->i_num.no_addr; + u64 blkno = ip->i_no_addr; rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); if (!rgd) @@ -1414,9 +1599,9 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) { - gfs2_free_uninit_di(rgd, ip->i_num.no_addr); + gfs2_free_uninit_di(rgd, ip->i_no_addr); gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); - gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); + gfs2_meta_wipe(ip, ip->i_no_addr, 1); } /** --- linux-source-2.6.22-2.6.22.orig/fs/gfs2/lops.c +++ linux-source-2.6.22-2.6.22/fs/gfs2/lops.c @@ -17,6 +17,7 @@ #include "gfs2.h" #include "incore.h" +#include "inode.h" #include "glock.h" #include "log.h" #include "lops.h" @@ -117,15 +118,13 @@ struct gfs2_log_descriptor *ld; struct gfs2_bufdata *bd1 = NULL, *bd2; unsigned int total = sdp->sd_log_num_buf; - unsigned int offset = sizeof(struct gfs2_log_descriptor); + unsigned int offset = BUF_OFFSET; unsigned int limit; unsigned int num; unsigned n; __be64 *ptr; - offset += sizeof(__be64) - 1; - offset &= ~(sizeof(__be64) - 1); - limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); + limit = buf_limit(sdp); /* for 4k blocks, limit = 503 */ bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); @@ -134,7 +133,6 @@ if (total > limit) num = limit; bh = gfs2_log_get_buf(sdp); - sdp->sd_log_num_hdrs++; ld = (struct gfs2_log_descriptor *)bh->b_data; ptr = (__be64 *)(bh->b_data + offset); ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); @@ -469,25 +467,28 @@ struct gfs2_inode *ip = GFS2_I(mapping->host); gfs2_log_lock(sdp); + if (!list_empty(&bd->bd_list_tr)) { + gfs2_log_unlock(sdp); + return; + } tr->tr_touched = 1; - if (list_empty(&bd->bd_list_tr) && - (ip->i_di.di_flags & GFS2_DIF_JDATA)) { + if (gfs2_is_jdata(ip)) { tr->tr_num_buf++; list_add(&bd->bd_list_tr, &tr->tr_list_buf); - gfs2_log_unlock(sdp); - gfs2_pin(sdp, bd->bd_bh); - tr->tr_num_buf_new++; - } else { - gfs2_log_unlock(sdp); } + gfs2_log_unlock(sdp); + if (!list_empty(&le->le_list)) + return; + gfs2_trans_add_gl(bd->bd_gl); - gfs2_log_lock(sdp); - if (list_empty(&le->le_list)) { - if (ip->i_di.di_flags & GFS2_DIF_JDATA) - sdp->sd_log_num_jdata++; - sdp->sd_log_num_databuf++; - list_add(&le->le_list, &sdp->sd_log_le_databuf); + if (gfs2_is_jdata(ip)) { + sdp->sd_log_num_jdata++; + gfs2_pin(sdp, bd->bd_bh); + tr->tr_num_databuf_new++; } + sdp->sd_log_num_databuf++; + gfs2_log_lock(sdp); + list_add(&le->le_list, &sdp->sd_log_le_databuf); gfs2_log_unlock(sdp); } @@ -520,7 +521,6 @@ LIST_HEAD(started); struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; struct buffer_head *bh = NULL,*bh1 = NULL; - unsigned int offset = sizeof(struct gfs2_log_descriptor); struct gfs2_log_descriptor *ld; unsigned int limit; unsigned int total_dbuf = sdp->sd_log_num_databuf; @@ -528,9 +528,7 @@ unsigned int num, n; __be64 *ptr = NULL; - offset += 2*sizeof(__be64) - 1; - offset &= ~(2*sizeof(__be64) - 1); - limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); + limit = databuf_limit(sdp); /* * Start writing ordered buffers, write journaled buffers @@ -581,10 +579,10 @@ gfs2_log_unlock(sdp); if (!bh) { bh = gfs2_log_get_buf(sdp); - sdp->sd_log_num_hdrs++; ld = (struct gfs2_log_descriptor *) bh->b_data; - ptr = (__be64 *)(bh->b_data + offset); + ptr = (__be64 *)(bh->b_data + + DATABUF_OFFSET); ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); ld->ld_header.mh_type = @@ -605,7 +603,7 @@ if (unlikely(magic != 0)) set_buffer_escaped(bh1); gfs2_log_lock(sdp); - if (n++ > num) + if (++n >= num) break; } else if (!bh1) { total_dbuf--; @@ -622,6 +620,7 @@ } gfs2_log_unlock(sdp); if (bh) { + set_buffer_mapped(bh); set_buffer_dirty(bh); ll_rw_block(WRITE, 1, &bh); bh = NULL; --- linux-source-2.6.22-2.6.22.orig/fs/locks.c +++ linux-source-2.6.22-2.6.22/fs/locks.c @@ -786,7 +786,7 @@ if (request->fl_flags & FL_ACCESS) goto out; locks_copy_lock(new_fl, request); - locks_insert_lock(&inode->i_flock, new_fl); + locks_insert_lock(before, new_fl); new_fl = NULL; error = 0; @@ -1733,6 +1733,7 @@ struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1803,7 +1804,15 @@ * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + /* + * we need that spin_lock here - it prevents reordering between + * update of inode->i_flock and check for it done in close(). + * rcu_read_lock() wouldn't do. + */ + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } @@ -1859,6 +1868,7 @@ struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; struct inode *inode; + struct file *f; int error; if (file_lock == NULL) @@ -1929,7 +1939,10 @@ * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + spin_lock(¤t->files->file_lock); + f = fcheck(fd); + spin_unlock(¤t->files->file_lock); + if (!error && f != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } --- linux-source-2.6.22-2.6.22.orig/fs/hpfs/namei.c +++ linux-source-2.6.22-2.6.22/fs/hpfs/namei.c @@ -426,7 +426,7 @@ /*printk("HPFS: truncating file before delete.\n");*/ newattrs.ia_size = 0; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, NULL, &newattrs); put_write_access(inode); if (!err) goto again; --- linux-source-2.6.22-2.6.22.orig/fs/ext4/extents.c +++ linux-source-2.6.22-2.6.22/fs/ext4/extents.c @@ -1445,7 +1445,7 @@ static void ext4_ext_put_in_cache(struct inode *inode, __u32 block, - __u32 len, __u32 start, int type) + __u32 len, ext4_fsblk_t start, int type) { struct ext4_ext_cache *cex; BUG_ON(len == 0); --- linux-source-2.6.22-2.6.22.orig/fs/ext4/namei.c +++ linux-source-2.6.22-2.6.22/fs/ext4/namei.c @@ -140,7 +140,8 @@ struct dx_map_entry { u32 hash; - u32 offs; + u16 offs; + u16 size; }; #ifdef CONFIG_EXT4_INDEX @@ -379,13 +380,28 @@ entries = (struct dx_entry *) (((char *)&root->info) + root->info.info_length); - assert(dx_get_limit(entries) == dx_root_limit(dir, - root->info.info_length)); + + if (dx_get_limit(entries) != dx_root_limit(dir, + root->info.info_length)) { + ext4_warning(dir->i_sb, __FUNCTION__, + "dx entry: limit != root limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail; + } + dxtrace (printk("Look up %x", hash)); while (1) { count = dx_get_count(entries); - assert (count && count <= dx_get_limit(entries)); + if (!count || count > dx_get_limit(entries)) { + ext4_warning(dir->i_sb, __FUNCTION__, + "dx entry: no count or count > limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail2; + } + p = entries + 1; q = entries + count - 1; while (p <= q) @@ -423,8 +439,15 @@ if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err))) goto fail2; at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); + if (dx_get_limit(entries) != dx_node_limit (dir)) { + ext4_warning(dir->i_sb, __FUNCTION__, + "dx entry: limit != node limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail2; + } frame++; + frame->bh = NULL; } fail2: while (frame >= frame_in) { @@ -432,6 +455,10 @@ frame--; } fail: + if (*err == ERR_BAD_DX_DIR) + ext4_warning(dir->i_sb, __FUNCTION__, + "Corrupt dir inode %ld, running e2fsck is " + "recommended.", dir->i_ino); return NULL; } @@ -671,6 +698,10 @@ * Directory block splitting, compacting */ +/* + * Create map of hash values, offsets, and sizes, stored at end of block. + * Returns number of entries mapped. + */ static int dx_make_map (struct ext4_dir_entry_2 *de, int size, struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) { @@ -684,7 +715,8 @@ ext4fs_dirhash(de->name, de->name_len, &h); map_tail--; map_tail->hash = h.hash; - map_tail->offs = (u32) ((char *) de - base); + map_tail->offs = (u16) ((char *) de - base); + map_tail->size = le16_to_cpu(de->rec_len); count++; cond_resched(); } @@ -694,6 +726,7 @@ return count; } +/* Sort map by hash value */ static void dx_sort_map (struct dx_map_entry *map, unsigned count) { struct dx_map_entry *p, *q, *top = map + count - 1; @@ -1079,6 +1112,10 @@ } #ifdef CONFIG_EXT4_INDEX +/* + * Move count entries from end of map between two memory locations. + * Returns pointer to last entry moved. + */ static struct ext4_dir_entry_2 * dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) { @@ -1097,6 +1134,10 @@ return (struct ext4_dir_entry_2 *) (to - rec_len); } +/* + * Compact each dir entry in the range to the minimal rec_len. + * Returns pointer to last entry in range. + */ static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size) { struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base; @@ -1119,6 +1160,11 @@ return prev; } +/* + * Split a full leaf block to make room for a new dir entry. + * Allocate a new block, and move entries so that they are approx. equally full. + * Returns pointer to de in block into which the new entry will be inserted. + */ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, struct buffer_head **bh,struct dx_frame *frame, struct dx_hash_info *hinfo, int *error) @@ -1130,7 +1176,7 @@ u32 hash2; struct dx_map_entry *map; char *data1 = (*bh)->b_data, *data2; - unsigned split; + unsigned split, move, size, i; struct ext4_dir_entry_2 *de = NULL, *de2; int err = 0; @@ -1158,8 +1204,19 @@ count = dx_make_map ((struct ext4_dir_entry_2 *) data1, blocksize, hinfo, map); map -= count; - split = count/2; // need to adjust to actual middle dx_sort_map (map, count); + /* Split the existing block in the middle, size-wise */ + size = 0; + move = 0; + for (i = count-1; i >= 0; i--) { + /* is more than half of this entry in 2nd half of the block? */ + if (size + map[i].size/2 > blocksize/2) + break; + size += map[i].size; + move++; + } + /* map index at which we will split */ + split = count - move; hash2 = map[split].hash; continued = hash2 == map[split - 1].hash; dxtrace(printk("Split block %i at %x, %i/%i\n", --- linux-source-2.6.22-2.6.22.orig/fs/stat.c +++ linux-source-2.6.22-2.6.22/fs/stat.c @@ -306,7 +306,7 @@ error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(nd.dentry); + error = security_inode_readlink(nd.dentry, nd.mnt); if (!error) { touch_atime(nd.mnt, nd.dentry); error = inode->i_op->readlink(nd.dentry, buf, bufsiz); --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/nfs3acl.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/nfs3acl.c @@ -37,7 +37,7 @@ fh = fh_copy(&resp->fh, &argp->fh); if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) - RETURN_STATUS(nfserr_inval); + RETURN_STATUS(nfserr); if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) RETURN_STATUS(nfserr_inval); --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/nfsfh.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/nfsfh.c @@ -565,13 +565,23 @@ case FSID_DEV: case FSID_ENCODE_DEV: case FSID_MAJOR_MINOR: - return FSIDSOURCE_DEV; + if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags + & FS_REQUIRES_DEV) + return FSIDSOURCE_DEV; + break; case FSID_NUM: - return FSIDSOURCE_FSID; - default: if (fhp->fh_export->ex_flags & NFSEXP_FSID) return FSIDSOURCE_FSID; - else - return FSIDSOURCE_UUID; + break; + default: + break; } + /* either a UUID type filehandle, or the filehandle doesn't + * match the export. + */ + if (fhp->fh_export->ex_flags & NFSEXP_FSID) + return FSIDSOURCE_FSID; + if (fhp->fh_export->ex_uuid) + return FSIDSOURCE_UUID; + return FSIDSOURCE_DEV; } --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/nfs2acl.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/nfs2acl.c @@ -41,7 +41,7 @@ fh = fh_copy(&resp->fh, &argp->fh); if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP))) - RETURN_STATUS(nfserr_inval); + RETURN_STATUS(nfserr); if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) RETURN_STATUS(nfserr_inval); --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/vfs.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/vfs.c @@ -358,7 +358,7 @@ err = nfserr_notsync; if (!check_guard || guardtime == inode->i_ctime.tv_sec) { fh_lock(fhp); - host_err = notify_change(dentry, iap); + host_err = notify_change(dentry, fhp->fh_export->ex_mnt, iap); err = nfserrno(host_err); fh_unlock(fhp); } @@ -378,11 +378,12 @@ #if defined(CONFIG_NFSD_V2_ACL) || \ defined(CONFIG_NFSD_V3_ACL) || \ defined(CONFIG_NFSD_V4) -static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) +static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt, + char *key, void **buf) { ssize_t buflen; - buflen = vfs_getxattr(dentry, key, NULL, 0); + buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL); if (buflen <= 0) return buflen; @@ -390,13 +391,14 @@ if (!*buf) return -ENOMEM; - return vfs_getxattr(dentry, key, *buf, buflen); + return vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL); } #endif #if defined(CONFIG_NFSD_V4) static int -set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) +set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt, + struct posix_acl *pacl, char *key) { int len; size_t buflen; @@ -415,7 +417,7 @@ goto out; } - error = vfs_setxattr(dentry, key, buf, len, 0); + error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL); out: kfree(buf); return error; @@ -428,6 +430,7 @@ __be32 error; int host_error; struct dentry *dentry; + struct vfsmount *mnt; struct inode *inode; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; @@ -438,6 +441,7 @@ goto out; dentry = fhp->fh_dentry; + mnt = fhp->fh_export->ex_mnt; inode = dentry->d_inode; if (S_ISDIR(inode->i_mode)) flags = NFS4_ACL_DIR; @@ -449,12 +453,14 @@ } else if (host_error < 0) goto out_nfserr; - host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); + host_error = set_nfsv4_acl_one(dentry, mnt, pacl, + POSIX_ACL_XATTR_ACCESS); if (host_error < 0) goto out_nfserr; if (S_ISDIR(inode->i_mode)) { - host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); + host_error = set_nfsv4_acl_one(dentry, mnt, dpacl, + POSIX_ACL_XATTR_DEFAULT); if (host_error < 0) goto out_nfserr; } @@ -474,13 +480,13 @@ } static struct posix_acl * -_get_posix_acl(struct dentry *dentry, char *key) +_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key) { void *buf = NULL; struct posix_acl *pacl = NULL; int buflen; - buflen = nfsd_getxattr(dentry, key, &buf); + buflen = nfsd_getxattr(dentry, mnt, key, &buf); if (!buflen) buflen = -ENODATA; if (buflen <= 0) @@ -492,14 +498,15 @@ } int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl) +nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct vfsmount *mnt, struct nfs4_acl **acl) { struct inode *inode = dentry->d_inode; int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS); + pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS); if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA) pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); if (IS_ERR(pacl)) { @@ -509,7 +516,7 @@ } if (S_ISDIR(inode->i_mode)) { - dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT); + dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT); if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA) dpacl = NULL; else if (IS_ERR(dpacl)) { @@ -893,13 +900,13 @@ return err; } -static void kill_suid(struct dentry *dentry) +static void kill_suid(struct dentry *dentry, struct vfsmount *mnt) { struct iattr ia; ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; mutex_lock(&dentry->d_inode->i_mutex); - notify_change(dentry, &ia); + notify_change(dentry, mnt, &ia); mutex_unlock(&dentry->d_inode->i_mutex); } @@ -958,7 +965,7 @@ /* clear setuid/setgid flag after write */ if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) - kill_suid(dentry); + kill_suid(dentry, exp->ex_mnt); if (host_err >= 0 && stable) { static ino_t last_ino; @@ -1115,6 +1122,7 @@ int type, dev_t rdev, struct svc_fh *resfhp) { struct dentry *dentry, *dchild = NULL; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1131,6 +1139,7 @@ goto out; dentry = fhp->fh_dentry; + exp = fhp->fh_export; dirp = dentry->d_inode; err = nfserr_notdir; @@ -1147,7 +1156,7 @@ host_err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); + err = fh_compose(resfhp, exp, dchild, fhp); if (err) goto out; } else { @@ -1186,13 +1195,14 @@ host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); break; case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); + host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); + host_err = vfs_mknod(dirp, dchild, exp->ex_mnt, iap->ia_mode, + rdev); break; default: printk("nfsd: bad file type %o in nfsd_create\n", type); @@ -1201,7 +1211,7 @@ if (host_err < 0) goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) { + if (EX_ISSYNC(exp)) { err = nfserrno(nfsd_sync_dir(dentry)); write_inode_now(dchild->d_inode, 1); } @@ -1433,6 +1443,7 @@ struct iattr *iap) { struct dentry *dentry, *dnew; + struct svc_export *exp; __be32 err, cerr; int host_err; umode_t mode; @@ -1459,6 +1470,7 @@ if (iap && (iap->ia_valid & ATTR_MODE)) mode = iap->ia_mode & S_IALLUGO; + exp = fhp->fh_export; if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) @@ -1466,20 +1478,22 @@ else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); + host_err = vfs_symlink(dentry->d_inode, dnew, + exp->ex_mnt, path_alloced, mode); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); + host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_mnt, path, + mode); if (!host_err) { - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); } err = nfserrno(host_err); fh_unlock(fhp); - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); + cerr = fh_compose(resfhp, exp, dnew, fhp); dput(dnew); if (err==0) err = cerr; out: @@ -1529,7 +1543,8 @@ dold = tfhp->fh_dentry; dest = dold->d_inode; - host_err = vfs_link(dold, dirp, dnew); + host_err = vfs_link(dold, tfhp->fh_export->ex_mnt, dirp, + dnew, ffhp->fh_export->ex_mnt); if (!host_err) { if (EX_ISSYNC(ffhp->fh_export)) { err = nfserrno(nfsd_sync_dir(ddir)); @@ -1622,7 +1637,8 @@ host_err = -EPERM; } else #endif - host_err = vfs_rename(fdir, odentry, tdir, ndentry); + host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_mnt, + tdir, ndentry, tfhp->fh_export->ex_mnt); if (!host_err && EX_ISSYNC(tfhp->fh_export)) { host_err = nfsd_sync_dir(tdentry); if (!host_err) @@ -1658,6 +1674,7 @@ char *fname, int flen) { struct dentry *dentry, *rdentry; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1672,6 +1689,7 @@ fh_lock_nested(fhp, I_MUTEX_PARENT); dentry = fhp->fh_dentry; dirp = dentry->d_inode; + exp = fhp->fh_export; rdentry = lookup_one_len(fname, dentry, flen); host_err = PTR_ERR(rdentry); @@ -1689,21 +1707,21 @@ if (type != S_IFDIR) { /* It's UNLINK */ #ifdef MSNFS - if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + if ((exp->ex_flags & NFSEXP_MSNFS) && (atomic_read(&rdentry->d_count) > 1)) { host_err = -EPERM; } else #endif - host_err = vfs_unlink(dirp, rdentry); + host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt); } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry); + host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt); } dput(rdentry); if (host_err) goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); out_nfserr: @@ -1890,7 +1908,7 @@ raparm_hash[i].pb_head = NULL; spin_lock_init(&raparm_hash[i].pb_lock); } - nperbucket = cache_size >> RAPARM_HASH_BITS; + nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE); for (i = 0; i < cache_size - 1; i++) { if (i % nperbucket == 0) raparm_hash[j++].pb_head = raparml + i; @@ -1926,7 +1944,8 @@ return ERR_PTR(-EOPNOTSUPP); } - size = nfsd_getxattr(fhp->fh_dentry, name, &value); + size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, name, + &value); if (size < 0) return ERR_PTR(size); @@ -1938,6 +1957,7 @@ int nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) { + struct vfsmount *mnt; struct inode *inode = fhp->fh_dentry->d_inode; char *name; void *value = NULL; @@ -1970,13 +1990,16 @@ } else size = 0; + mnt = fhp->fh_export->ex_mnt; if (size) - error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); + error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0, + NULL); else { if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) error = 0; else { - error = vfs_removexattr(fhp->fh_dentry, name); + error = vfs_removexattr(fhp->fh_dentry, mnt, name, + NULL); if (error == -ENODATA) error = 0; } --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/nfs4recover.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/nfs4recover.c @@ -156,7 +156,8 @@ dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); goto out_put; } - status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt, + S_IRWXU); out_put: dput(dentry); out_unlock: @@ -260,7 +261,7 @@ return -EINVAL; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_unlink(dir->d_inode, dentry); + status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } @@ -275,7 +276,7 @@ * a kernel from the future.... */ nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_rmdir(dir->d_inode, dentry); + status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } --- linux-source-2.6.22-2.6.22.orig/fs/nfsd/nfs4xdr.c +++ linux-source-2.6.22-2.6.22/fs/nfsd/nfs4xdr.c @@ -1453,7 +1453,8 @@ err = vfs_getattr(exp->ex_mnt, dentry, &stat); if (err) goto out_nfserr; - if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || + if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | + FATTR4_WORD0_MAXNAME)) || (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL))) { err = vfs_statfs(dentry, &statfs); @@ -1469,7 +1470,7 @@ } if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_SUPPORTED_ATTRS)) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_mnt, &acl); aclsupport = (err == 0); if (bmval0 & FATTR4_WORD0_ACL) { if (err == -EOPNOTSUPP) @@ -1699,7 +1700,7 @@ if (bmval0 & FATTR4_WORD0_MAXNAME) { if ((buflen -= 4) < 0) goto out_resource; - WRITE32(~(u32) 0); + WRITE32(statfs.f_namelen); } if (bmval0 & FATTR4_WORD0_MAXREAD) { if ((buflen -= 8) < 0) --- linux-source-2.6.22-2.6.22.orig/fs/xattr.c +++ linux-source-2.6.22-2.6.22/fs/xattr.c @@ -69,8 +69,8 @@ } int -vfs_setxattr(struct dentry *dentry, char *name, void *value, - size_t size, int flags) +vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + void *value, size_t size, int flags, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -80,7 +80,7 @@ return error; mutex_lock(&inode->i_mutex); - error = security_inode_setxattr(dentry, name, value, size, flags); + error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file); if (error) goto out; error = -EOPNOTSUPP; @@ -88,7 +88,7 @@ error = inode->i_op->setxattr(dentry, name, value, size, flags); if (!error) { fsnotify_xattr(dentry); - security_inode_post_setxattr(dentry, name, value, + security_inode_post_setxattr(dentry, mnt, name, value, size, flags); } } else if (!strncmp(name, XATTR_SECURITY_PREFIX, @@ -106,7 +106,8 @@ EXPORT_SYMBOL_GPL(vfs_setxattr); ssize_t -vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) +vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + void *value, size_t size, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -115,7 +116,7 @@ if (error) return error; - error = security_inode_getxattr(dentry, name); + error = security_inode_getxattr(dentry, mnt, name, file); if (error) return error; @@ -142,18 +143,20 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); ssize_t -vfs_listxattr(struct dentry *d, char *list, size_t size) +vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, + size_t size, struct file *file) { + struct inode *inode = dentry->d_inode; ssize_t error; - error = security_inode_listxattr(d); + error = security_inode_listxattr(dentry, mnt, file); if (error) return error; error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { - error = d->d_inode->i_op->listxattr(d, list, size); - } else { - error = security_inode_listsecurity(d->d_inode, list, size); + if (inode->i_op && inode->i_op->listxattr) + error = inode->i_op->listxattr(dentry, list, size); + else { + error = security_inode_listsecurity(inode, list, size); if (size && error > size) error = -ERANGE; } @@ -162,7 +165,8 @@ EXPORT_SYMBOL_GPL(vfs_listxattr); int -vfs_removexattr(struct dentry *dentry, char *name) +vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name, + struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -174,7 +178,7 @@ if (error) return error; - error = security_inode_removexattr(dentry, name); + error = security_inode_removexattr(dentry, mnt, name, file); if (error) return error; @@ -193,8 +197,8 @@ * Extended attribute SET operations */ static long -setxattr(struct dentry *d, char __user *name, void __user *value, - size_t size, int flags) +setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + void __user *value, size_t size, int flags, struct file *file) { int error; void *kvalue = NULL; @@ -221,7 +225,7 @@ } } - error = vfs_setxattr(d, kname, kvalue, size, flags); + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); kfree(kvalue); return error; } @@ -236,7 +240,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); path_release(&nd); return error; } @@ -251,7 +255,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = setxattr(nd.dentry, name, value, size, flags); + error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); path_release(&nd); return error; } @@ -269,7 +273,7 @@ return error; dentry = f->f_path.dentry; audit_inode(NULL, dentry->d_inode); - error = setxattr(dentry, name, value, size, flags); + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, f); fput(f); return error; } @@ -278,7 +282,8 @@ * Extended attribute GET operations */ static ssize_t -getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) +getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + void __user *value, size_t size, struct file *file) { ssize_t error; void *kvalue = NULL; @@ -298,7 +303,7 @@ return -ENOMEM; } - error = vfs_getxattr(d, kname, kvalue, size); + error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file); if (error > 0) { if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; @@ -321,7 +326,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = getxattr(nd.dentry, name, value, size); + error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); path_release(&nd); return error; } @@ -336,7 +341,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = getxattr(nd.dentry, name, value, size); + error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); path_release(&nd); return error; } @@ -351,7 +356,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry->d_inode); - error = getxattr(f->f_path.dentry, name, value, size); + error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f); fput(f); return error; } @@ -360,7 +365,8 @@ * Extended attribute LIST operations */ static ssize_t -listxattr(struct dentry *d, char __user *list, size_t size) +listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, + size_t size, struct file *file) { ssize_t error; char *klist = NULL; @@ -373,7 +379,7 @@ return -ENOMEM; } - error = vfs_listxattr(d, klist, size); + error = vfs_listxattr(dentry, mnt, klist, size, file); if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; @@ -395,7 +401,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = listxattr(nd.dentry, list, size); + error = listxattr(nd.dentry, nd.mnt, list, size, NULL); path_release(&nd); return error; } @@ -409,7 +415,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = listxattr(nd.dentry, list, size); + error = listxattr(nd.dentry, nd.mnt, list, size, NULL); path_release(&nd); return error; } @@ -424,7 +430,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry->d_inode); - error = listxattr(f->f_path.dentry, list, size); + error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f); fput(f); return error; } @@ -433,7 +439,8 @@ * Extended attribute REMOVE operations */ static long -removexattr(struct dentry *d, char __user *name) +removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, + struct file *file) { int error; char kname[XATTR_NAME_MAX + 1]; @@ -444,7 +451,7 @@ if (error < 0) return error; - return vfs_removexattr(d, kname); + return vfs_removexattr(dentry, mnt, kname, file); } asmlinkage long @@ -456,7 +463,7 @@ error = user_path_walk(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, nd.mnt, name, NULL); path_release(&nd); return error; } @@ -470,7 +477,7 @@ error = user_path_walk_link(path, &nd); if (error) return error; - error = removexattr(nd.dentry, name); + error = removexattr(nd.dentry, nd.mnt, name, NULL); path_release(&nd); return error; } @@ -487,7 +494,7 @@ return error; dentry = f->f_path.dentry; audit_inode(NULL, dentry->d_inode); - error = removexattr(dentry, name); + error = removexattr(dentry, f->f_path.mnt, name, f); fput(f); return error; } --- linux-source-2.6.22-2.6.22.orig/fs/cifs/cifsglob.h +++ linux-source-2.6.22-2.6.22/fs/cifs/cifsglob.h @@ -442,6 +442,17 @@ #define CIFS_LARGE_BUFFER 2 #define CIFS_IOVEC 4 /* array of response buffers */ +/* Type of Request to SendReceive2 */ +#define CIFS_STD_OP 0 /* normal request timeout */ +#define CIFS_LONG_OP 1 /* long op (up to 45 sec, oplock time) */ +#define CIFS_VLONG_OP 2 /* sloow op - can take up to 180 seconds */ +#define CIFS_BLOCKING_OP 4 /* operation can block */ +#define CIFS_ASYNC_OP 8 /* do not wait for response */ +#define CIFS_TIMEOUT_MASK 0x00F /* only one of 5 above set in req */ +#define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */ +#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */ +#define CIFS_NO_RESP 0x040 /* no response buffer required */ + /* Security Flags: indicate type of session setup needed */ #define CIFSSEC_MAY_SIGN 0x00001 #define CIFSSEC_MAY_NTLM 0x00002 --- linux-source-2.6.22-2.6.22.orig/fs/cifs/connect.c +++ linux-source-2.6.22-2.6.22/fs/cifs/connect.c @@ -2273,7 +2273,7 @@ pSMB->req_no_secext.ByteCount = cpu_to_le16(count); rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, - &bytes_returned, 1); + &bytes_returned, CIFS_LONG_OP); if (rc) { /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */ } else if ((smb_buffer_response->WordCount == 3) @@ -2559,7 +2559,7 @@ pSMB->req.ByteCount = cpu_to_le16(count); rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, - &bytes_returned, 1); + &bytes_returned, CIFS_LONG_OP); if (smb_buffer_response->Status.CifsError == cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)) @@ -2985,7 +2985,7 @@ pSMB->req.ByteCount = cpu_to_le16(count); rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, - &bytes_returned, 1); + &bytes_returned, CIFS_LONG_OP); if (rc) { /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */ } else if ((smb_buffer_response->WordCount == 3) @@ -3256,7 +3256,8 @@ pSMB->hdr.smb_buf_length += count; pSMB->ByteCount = cpu_to_le16(count); - rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0); + rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, + CIFS_STD_OP); /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ /* above now done in SendReceive */ --- linux-source-2.6.22-2.6.22.orig/fs/cifs/cifsproto.h +++ linux-source-2.6.22-2.6.22/fs/cifs/cifsproto.h @@ -48,10 +48,12 @@ struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , int * /* bytes returned */ , const int long_op); +extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, + struct smb_hdr *in_buf, int flags); extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, - struct kvec *, int /* nvec to send */, - int * /* type of buf returned */ , const int long_op); -extern int SendReceiveBlockingLock(const unsigned int /* xid */ , + struct kvec *, int /* nvec to send */, + int * /* type of buf returned */ , const int flags); +extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , --- linux-source-2.6.22-2.6.22.orig/fs/cifs/asn1.c +++ linux-source-2.6.22-2.6.22/fs/cifs/asn1.c @@ -182,6 +182,11 @@ } } } + + /* don't trust len bigger than ctx buffer */ + if (*len > ctx->end - ctx->pointer) + return 0; + return 1; } @@ -199,6 +204,10 @@ if (!asn1_length_decode(ctx, &def, &len)) return 0; + /* primitive shall be definite, indefinite shall be constructed */ + if (*con == ASN1_PRI && !def) + return 0; + if (def) *eoc = ctx->pointer + len; else @@ -385,7 +394,12 @@ unsigned long *optr; size = eoc - ctx->pointer + 1; - *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC); + + /* first subid actually encodes first two subids */ + if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) + return 0; + + *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) { return 0; } --- linux-source-2.6.22-2.6.22.orig/fs/cifs/cifssmb.c +++ linux-source-2.6.22-2.6.22/fs/cifs/cifssmb.c @@ -660,9 +660,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) { struct smb_hdr *smb_buffer; - struct smb_hdr *smb_buffer_response; /* BB removeme BB */ int rc = 0; - int length; cFYI(1, ("In tree disconnect")); /* @@ -699,16 +697,12 @@ if (rc) { up(&tcon->tconSem); return rc; - } else { - smb_buffer_response = smb_buffer; /* BB removeme BB */ } - rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, - &length, 0); + + rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0); if (rc) cFYI(1, ("Tree disconnect failed %d", rc)); - if (smb_buffer) - cifs_small_buf_release(smb_buffer); up(&tcon->tconSem); /* No need to return error on this operation if tid invalidated and @@ -722,10 +716,8 @@ int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) { - struct smb_hdr *smb_buffer_response; LOGOFF_ANDX_REQ *pSMB; int rc = 0; - int length; cFYI(1, ("In SMBLogoff for session disconnect")); if (ses) @@ -744,9 +736,7 @@ return rc; } - smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ - - if(ses->server) { + if (ses->server) { pSMB->hdr.Mid = GetNextMid(ses->server); if(ses->server->secMode & @@ -757,8 +747,7 @@ pSMB->hdr.Uid = ses->Suid; pSMB->AndXCommand = 0xFF; - rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, - smb_buffer_response, &length, 0); + rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0); if (ses->server) { atomic_dec(&ses->server->socketUseCount); if (atomic_read(&ses->server->socketUseCount) == 0) { @@ -769,7 +758,6 @@ } } up(&ses->sesSem); - cifs_small_buf_release(pSMB); /* if session dead then we do not need to do ulogoff, since server closed smb session, no sense reporting @@ -1143,7 +1131,7 @@ pSMB->ByteCount = cpu_to_le16(count); /* long_op set to 1 to allow for oplock break timeouts */ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 1); + (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP); cifs_stats_inc(&tcon->num_opens); if (rc) { cFYI(1, ("Error in Open = %d", rc)); @@ -1257,7 +1245,7 @@ pSMB->ByteCount = cpu_to_le16(count); /* long_op set to 1 to allow for oplock break timeouts */ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 1); + (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP); cifs_stats_inc(&tcon->num_opens); if (rc) { cFYI(1, ("Error in Open = %d", rc)); @@ -1335,9 +1323,8 @@ iov[0].iov_base = (char *)pSMB; iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; - rc = SendReceive2(xid, tcon->ses, iov, - 1 /* num iovecs */, - &resp_buf_type, 0); + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, + &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR); cifs_stats_inc(&tcon->num_reads); pSMBr = (READ_RSP *)iov[0].iov_base; if (rc) { @@ -1596,7 +1583,7 @@ int timeout = 0; __u16 count; - cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock)); + cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock)); rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); if (rc) @@ -1604,11 +1591,11 @@ pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ - if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) { - timeout = -1; /* no response expected */ + if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { + timeout = CIFS_ASYNC_OP; /* no response expected */ pSMB->Timeout = 0; } else if (waitFlag == TRUE) { - timeout = 3; /* blocking operation, no timeout */ + timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ } else { pSMB->Timeout = 0; @@ -1638,15 +1625,16 @@ if (waitFlag) { rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned); + cifs_small_buf_release(pSMB); } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, timeout); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, + timeout); + /* SMB buffer freed by function above */ } cifs_stats_inc(&tcon->num_locks); if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); } - cifs_small_buf_release(pSMB); /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -1666,7 +1654,9 @@ int rc = 0; int timeout = 0; int bytes_returned = 0; + int resp_buf_type = 0; __u16 params, param_offset, offset, byte_count, count; + struct kvec iov[1]; cFYI(1, ("Posix Lock")); @@ -1709,8 +1699,8 @@ (((char *) &pSMB->hdr.Protocol) + offset); parm_data->lock_type = cpu_to_le16(lock_type); - if(waitFlag) { - timeout = 3; /* blocking operation, no timeout */ + if (waitFlag) { + timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ parm_data->lock_flags = cpu_to_le16(1); pSMB->Timeout = cpu_to_le32(-1); } else @@ -1730,8 +1720,13 @@ rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned); } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, timeout); + iov[0].iov_base = (char *)pSMB; + iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, + &resp_buf_type, timeout); + pSMB = NULL; /* request buf already freed by SendReceive2. Do + not try to free it twice below on exit */ + pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base; } if (rc) { @@ -1766,6 +1761,11 @@ if (pSMB) cifs_small_buf_release(pSMB); + if (resp_buf_type == CIFS_SMALL_BUFFER) + cifs_small_buf_release(iov[0].iov_base); + else if (resp_buf_type == CIFS_LARGE_BUFFER) + cifs_buf_release(iov[0].iov_base); + /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -1778,8 +1778,6 @@ { int rc = 0; CLOSE_REQ *pSMB = NULL; - CLOSE_RSP *pSMBr = NULL; - int bytes_returned; cFYI(1, ("In CIFSSMBClose")); /* do not retry on dead session on close */ @@ -1789,13 +1787,10 @@ if (rc) return rc; - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ - pSMB->FileID = (__u16) smb_file_id; pSMB->LastWriteTime = 0xFFFFFFFF; pSMB->ByteCount = 0; - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); cifs_stats_inc(&tcon->num_closes); if (rc) { if(rc!=-EINTR) { @@ -1804,8 +1799,6 @@ } } - cifs_small_buf_release(pSMB); - /* Since session is dead, file will be closed on server already */ if(rc == -EAGAIN) rc = 0; @@ -2989,7 +2982,8 @@ iov[0].iov_base = (char *)pSMB; iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; - rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, + CIFS_STD_OP); cifs_stats_inc(&tcon->num_acl_get); if (rc) { cFYI(1, ("Send error in QuerySecDesc = %d", rc)); @@ -3634,8 +3628,6 @@ { int rc = 0; FINDCLOSE_REQ *pSMB = NULL; - CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */ - int bytes_returned; cFYI(1, ("In CIFSSMBFindClose")); rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); @@ -3647,16 +3639,13 @@ if (rc) return rc; - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ pSMB->FileID = searchHandle; pSMB->ByteCount = 0; - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) { cERROR(1, ("Send error in FindClose = %d", rc)); } cifs_stats_inc(&tcon->num_fclose); - cifs_small_buf_release(pSMB); /* Since session is dead, search handle closed on server already */ if (rc == -EAGAIN) @@ -4571,11 +4560,9 @@ __u16 fid, __u32 pid_of_opener, int SetAllocation) { struct smb_com_transaction2_sfi_req *pSMB = NULL; - struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; char *data_offset; struct file_end_of_file_info *parm_data; int rc = 0; - int bytes_returned = 0; __u16 params, param_offset, offset, byte_count, count; cFYI(1, ("SetFileSize (via SetFileInfo) %lld", @@ -4585,8 +4572,6 @@ if (rc) return rc; - pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; - pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); @@ -4637,18 +4622,14 @@ pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) { cFYI(1, ("Send error in SetFileInfo (SetFileSize) = %d", rc)); } - if (pSMB) - cifs_small_buf_release(pSMB); - - /* Note: On -EAGAIN error only caller can retry on handle based calls + /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ return rc; @@ -4665,10 +4646,8 @@ __u16 fid) { struct smb_com_transaction2_sfi_req *pSMB = NULL; - struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; char *data_offset; int rc = 0; - int bytes_returned = 0; __u16 params, param_offset, offset, byte_count, count; cFYI(1, ("Set Times (via SetFileInfo)")); @@ -4677,8 +4656,6 @@ if (rc) return rc; - pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; - /* At this point there is no need to override the current pid with the pid of the opener, but that could change if we someday use an existing handle (rather than opening one on the fly) */ @@ -4717,16 +4694,13 @@ pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); - memcpy(data_offset,data,sizeof(FILE_BASIC_INFO)); - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); + memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) { cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); } - cifs_small_buf_release(pSMB); - - /* Note: On -EAGAIN error only caller can retry on handle based calls + /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ return rc; @@ -5016,7 +4990,8 @@ pSMB->ByteCount = 0; rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, -1); + (struct smb_hdr *)pSMBr, &bytes_returned, + CIFS_ASYNC_OP); if (rc) { cFYI(1, ("Error in Notify = %d", rc)); } else { --- linux-source-2.6.22-2.6.22.orig/fs/cifs/transport.c +++ linux-source-2.6.22-2.6.22/fs/cifs/transport.c @@ -308,7 +308,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) { - if(long_op == -1) { + if (long_op == CIFS_ASYNC_OP) { /* oplock breaks must not be held up */ atomic_inc(&ses->server->inFlight); } else { @@ -337,7 +337,7 @@ they are allowed to block on server */ /* update # of requests on the wire to server */ - if (long_op < 3) + if (long_op != CIFS_BLOCKING_OP) atomic_inc(&ses->server->inFlight); spin_unlock(&GlobalMid_Lock); break; @@ -416,17 +416,48 @@ } } + +/* + * + * Send an SMB Request. No response info (other than return code) + * needs to be parsed. + * + * flags indicate the type of request buffer and how long to wait + * and whether to log NT STATUS code (error) before mapping it to POSIX error + * + */ +int +SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, + struct smb_hdr *in_buf, int flags) +{ + int rc; + struct kvec iov[1]; + int resp_buf_type; + + iov[0].iov_base = (char *)in_buf; + iov[0].iov_len = in_buf->smb_buf_length + 4; + flags |= CIFS_NO_RESP; + rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); +#ifdef CONFIG_CIFS_DEBUG2 + cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc)); +#endif + return rc; +} + int -SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, - struct kvec *iov, int n_vec, int * pRespBufType /* ret */, - const int long_op) +SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, + struct kvec *iov, int n_vec, int *pRespBufType /* ret */, + const int flags) { int rc = 0; + int long_op; unsigned int receive_len; unsigned long timeout; struct mid_q_entry *midQ; struct smb_hdr *in_buf = iov[0].iov_base; - + + long_op = flags & CIFS_TIMEOUT_MASK; + *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ if ((ses == NULL) || (ses->server == NULL)) { @@ -485,15 +516,22 @@ if(rc < 0) goto out; - if (long_op == -1) - goto out; - else if (long_op == 2) /* writes past end of file can take loong time */ + if (long_op == CIFS_STD_OP) + timeout = 15 * HZ; + else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */ timeout = 180 * HZ; - else if (long_op == 1) - timeout = 45 * HZ; /* should be greater than + else if (long_op == CIFS_LONG_OP) + timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else - timeout = 15 * HZ; + else if (long_op == CIFS_ASYNC_OP) + goto out; + else if (long_op == CIFS_BLOCKING_OP) + timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */ + else { + cERROR(1, ("unknown timeout flag %d", long_op)); + rc = -EIO; + goto out; + } /* wait for 15 seconds or until woken up due to response arriving or due to last connection to this server being unmounted */ @@ -568,7 +606,6 @@ } /* BB special case reconnect tid and uid here? */ - /* BB special case Errbadpassword and pwdexpired here */ rc = map_smb_to_linux_error(midQ->resp_buf); /* convert ByteCount if necessary */ @@ -578,8 +615,10 @@ (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) BCC(midQ->resp_buf) = le16_to_cpu(BCC_LE(midQ->resp_buf)); - midQ->resp_buf = NULL; /* mark it so will not be freed - by DeleteMidQEntry */ + if ((flags & CIFS_NO_RESP) == 0) + midQ->resp_buf = NULL; /* mark it so buf will + not be freed by + DeleteMidQEntry */ } else { rc = -EIO; cFYI(1,("Bad MID state?")); @@ -667,17 +706,25 @@ if(rc < 0) goto out; - if (long_op == -1) + if (long_op == CIFS_STD_OP) + timeout = 15 * HZ; + /* wait for 15 seconds or until woken up due to response arriving or + due to last connection to this server being unmounted */ + else if (long_op == CIFS_ASYNC_OP) goto out; - else if (long_op == 2) /* writes past end of file can take loong time */ + else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */ timeout = 180 * HZ; - else if (long_op == 1) - timeout = 45 * HZ; /* should be greater than + else if (long_op == CIFS_LONG_OP) + timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else - timeout = 15 * HZ; - /* wait for 15 seconds or until woken up due to response arriving or - due to last connection to this server being unmounted */ + else if (long_op == CIFS_BLOCKING_OP) + timeout = 0x7FFFFFFF; /* large but no so large as to wrap */ + else { + cERROR(1, ("unknown timeout flag %d", long_op)); + rc = -EIO; + goto out; + } + if (signal_pending(current)) { /* if signal pending do not hold up user for full smb timeout but we still give response a chance to complete */ @@ -817,7 +864,7 @@ pSMB->hdr.Mid = GetNextMid(ses->server); return SendReceive(xid, ses, in_buf, out_buf, - &bytes_returned, 0); + &bytes_returned, CIFS_STD_OP); } int @@ -849,7 +896,7 @@ to the same server. We may make this configurable later or use ses->maxReq */ - rc = wait_for_free_request(ses, 3); + rc = wait_for_free_request(ses, CIFS_BLOCKING_OP); if (rc) return rc; --- linux-source-2.6.22-2.6.22.orig/fs/cifs/file.c +++ linux-source-2.6.22-2.6.22/fs/cifs/file.c @@ -809,9 +809,9 @@ xid = GetXid(); if (*poffset > file->f_path.dentry->d_inode->i_size) - long_op = 2; /* writes past end of file can take a long time */ + long_op = CIFS_VLONG_OP; /* writes past EOF take long time */ else - long_op = 1; + long_op = CIFS_LONG_OP; for (total_written = 0; write_size > total_written; total_written += bytes_written) { @@ -858,7 +858,7 @@ } } else *poffset += bytes_written; - long_op = FALSE; /* subsequent writes fast - + long_op = CIFS_STD_OP; /* subsequent writes fast - 15 seconds is plenty */ } @@ -908,9 +908,9 @@ xid = GetXid(); if (*poffset > file->f_path.dentry->d_inode->i_size) - long_op = 2; /* writes past end of file can take a long time */ + long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */ else - long_op = 1; + long_op = CIFS_LONG_OP; for (total_written = 0; write_size > total_written; total_written += bytes_written) { @@ -976,7 +976,7 @@ } } else *poffset += bytes_written; - long_op = FALSE; /* subsequent writes fast - + long_op = CIFS_STD_OP; /* subsequent writes fast - 15 seconds is plenty */ } @@ -1276,7 +1276,7 @@ open_file->netfid, bytes_to_write, offset, &bytes_written, iov, n_iov, - 1); + CIFS_LONG_OP); atomic_dec(&open_file->wrtPending); if (rc || bytes_written < bytes_to_write) { cERROR(1,("Write2 ret %d, written = %d", --- linux-source-2.6.22-2.6.22.orig/fs/cifs/sess.c +++ linux-source-2.6.22-2.6.22/fs/cifs/sess.c @@ -488,8 +488,9 @@ BCC_LE(smb_buf) = cpu_to_le16(count); iov[1].iov_base = str_area; - iov[1].iov_len = count; - rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); + iov[1].iov_len = count; + rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, + CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR); /* SMB request buf freed in SendReceive2 */ cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); --- linux-source-2.6.22-2.6.22.orig/fs/xfs/linux-2.6/xfs_lrw.c +++ linux-source-2.6.22-2.6.22/fs/xfs/linux-2.6/xfs_lrw.c @@ -798,7 +798,7 @@ !capable(CAP_FSETID)) { error = xfs_write_clear_setuid(xip); if (likely(!error)) - error = -remove_suid(file->f_path.dentry); + error = -remove_suid(&file->f_path); if (unlikely(error)) { goto out_unlock_internal; } --- linux-source-2.6.22-2.6.22.orig/fs/9p/conv.c +++ linux-source-2.6.22-2.6.22/fs/9p/conv.c @@ -742,6 +742,7 @@ if (err) { kfree(fc); fc = ERR_PTR(err); + goto error; } if (buf_check_overflow(bufp)) { --- linux-source-2.6.22-2.6.22.orig/fs/reiserfs/xattr.c +++ linux-source-2.6.22-2.6.22/fs/reiserfs/xattr.c @@ -479,7 +479,7 @@ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock(&xinode->i_mutex); - err = notify_change(fp->f_path.dentry, &newattrs); + err = notify_change(fp->f_path.dentry, NULL, &newattrs); if (err) goto out_filp; @@ -775,7 +775,7 @@ if (dir->d_inode->i_nlink <= 2) { root = get_xa_root(inode->i_sb, XATTR_REPLACE); reiserfs_write_lock_xattrs(inode->i_sb); - err = vfs_rmdir(root->d_inode, dir); + err = vfs_rmdir(root->d_inode, dir, NULL); reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); } else { @@ -819,7 +819,7 @@ } if (!S_ISDIR(xafile->d_inode->i_mode)) - err = notify_change(xafile, attrs); + err = notify_change(xafile, NULL, attrs); dput(xafile); return err; @@ -871,7 +871,7 @@ goto out_dir; } - err = notify_change(dir, attrs); + err = notify_change(dir, NULL, attrs); unlock_kernel(); out_dir: --- linux-source-2.6.22-2.6.22.orig/fs/reiserfs/file.c +++ linux-source-2.6.22-2.6.22/fs/reiserfs/file.c @@ -1335,7 +1335,7 @@ if (count == 0) goto out; - res = remove_suid(file->f_path.dentry); + res = remove_suid(&file->f_path); if (res) goto out; --- linux-source-2.6.22-2.6.22.orig/fs/dnotify.c +++ linux-source-2.6.22-2.6.22/fs/dnotify.c @@ -20,6 +20,7 @@ #include #include #include +#include int dir_notify_enable __read_mostly = 1; @@ -66,6 +67,7 @@ struct dnotify_struct **prev; struct inode *inode; fl_owner_t id = current->files; + struct file *f; int error = 0; if ((arg & ~DN_MULTISHOT) == 0) { @@ -92,6 +94,15 @@ prev = &odn->dn_next; } + rcu_read_lock(); + f = fcheck(fd); + rcu_read_unlock(); + /* we'd lost the race with close(), sod off silently */ + /* note that inode->i_lock prevents reordering problems + * between accesses to descriptor table and ->i_dnotify */ + if (f != filp) + goto out_free; + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); if (error) goto out_free; --- linux-source-2.6.22-2.6.22.orig/fs/Kconfig +++ linux-source-2.6.22-2.6.22/fs/Kconfig @@ -1030,6 +1030,22 @@ endmenu +menu "Layered filesystems" + +config ECRYPT_FS + tristate "eCrypt filesystem layer support (EXPERIMENTAL)" + depends on EXPERIMENTAL && KEYS && CRYPTO && NET + help + Encrypted filesystem that operates on the VFS layer. See + to learn more about + eCryptfs. Userspace components are required and can be + obtained from . + + To compile this file system support as a module, choose M here: the + module will be called ecryptfs. + +endmenu + menu "Miscellaneous filesystems" config ADFS_FS @@ -1082,18 +1098,6 @@ To compile this file system support as a module, choose M here: the module will be called affs. If unsure, say N. -config ECRYPT_FS - tristate "eCrypt filesystem layer support (EXPERIMENTAL)" - depends on EXPERIMENTAL && KEYS && CRYPTO && NET - help - Encrypted filesystem that operates on the VFS layer. See - to learn more about - eCryptfs. Userspace components are required and can be - obtained from . - - To compile this file system support as a module, choose M here: the - module will be called ecryptfs. - config HFS_FS tristate "Apple Macintosh file system support (EXPERIMENTAL)" depends on BLOCK && EXPERIMENTAL --- linux-source-2.6.22-2.6.22.orig/fs/exec.c +++ linux-source-2.6.22-2.6.22/fs/exec.c @@ -586,18 +586,12 @@ int count; /* - * Tell all the sighand listeners that this sighand has - * been detached. The signalfd_detach() function grabs the - * sighand lock, if signal listeners are present on the sighand. - */ - signalfd_detach(tsk); - - /* * If we don't share sighandlers, then we aren't sharing anything * and we can just re-use it all. */ if (atomic_read(&oldsighand->count) <= 1) { BUG_ON(atomic_read(&sig->count) != 1); + signalfd_detach(tsk); exit_itimers(sig); return 0; } @@ -736,6 +730,7 @@ sig->flags = 0; no_thread_group: + signalfd_detach(tsk); exit_itimers(sig); if (leader) release_task(leader); @@ -890,9 +885,12 @@ */ current->mm->task_size = TASK_SIZE; - if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || - file_permission(bprm->file, MAY_READ) || - (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { + if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) { + suid_keys(current); + current->mm->dumpable = suid_dumpable; + current->pdeath_signal = 0; + } else if (file_permission(bprm->file, MAY_READ) || + (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { suid_keys(current); current->mm->dumpable = suid_dumpable; } @@ -983,8 +981,10 @@ { int unsafe; - if (bprm->e_uid != current->uid) + if (bprm->e_uid != current->uid) { suid_keys(current); + current->pdeath_signal = 0; + } exec_keys(current); task_lock(current); @@ -1484,9 +1484,23 @@ return core_waiters; } +#define CORE_ENV_MAX_ARGS 8 + int do_coredump(long signr, int exit_code, struct pt_regs * regs) { char corename[CORENAME_MAX_SIZE + 1]; + char *core_argv[2]; + char *core_envp[CORE_ENV_MAX_ARGS + 1]; + /* Gotta love scope... */ + char core_pid[CORENAME_MAX_SIZE + 1]; + char core_uid[CORENAME_MAX_SIZE + 1]; + char core_gid[CORENAME_MAX_SIZE + 1]; + char core_signal[CORENAME_MAX_SIZE + 1]; + char core_time[CORENAME_MAX_SIZE + 1]; + char core_hostname[CORENAME_MAX_SIZE + 1]; + char core_comm[CORENAME_MAX_SIZE + 1]; + char core_rlim[CORENAME_MAX_SIZE + 1]; + int old_rlim = -1; struct mm_struct *mm = current->mm; struct linux_binfmt * binfmt; struct inode * inode; @@ -1495,6 +1509,7 @@ int fsuid = current->fsuid; int flag = 0; int ispipe = 0; + struct subprocess_info *sub_info = NULL; audit_core_dumps(signr); @@ -1522,14 +1537,27 @@ if (retval < 0) goto fail; + /* For piped core's, we rely on the script to limit what it writes + * out. Since we aren't writing directly to the fs, we shouldn't + * worry too much (and pipe should infer we always want to do the + * core). We tell the script the original value for rlim_cur via + * env, so it can make intelligent decisions. */ + if (core_pattern[0] == '|') { + old_rlim = current->signal->rlim[RLIMIT_CORE].rlim_cur; + current->signal->rlim[RLIMIT_CORE].rlim_cur = + 1024 * 1024 * 1024; + } + /* * Clear any false indication of pending signals that might * be seen by the filesystem code called to write the core file. */ clear_thread_flag(TIF_SIGPENDING); - if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) + if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump && + core_pattern[0] != '|') { goto fail_unlock; + } /* * lock_kernel() because format_corename() is controlled by sysctl, which @@ -1539,8 +1567,43 @@ ispipe = format_corename(corename, core_pattern, signr); unlock_kernel(); if (ispipe) { + int i = 0; + struct timeval tv; + +#define CORE_ENV_ADD(__buf, __fmt, __arg) \ +do { \ +if (i < CORE_ENV_MAX_ARGS ) { \ + snprintf(__buf, sizeof(__buf), __fmt, __arg); \ + core_envp[i++] = __buf; \ +} else \ + WARN_ON(1); \ +} while(0) + + /* Create the env */ + CORE_ENV_ADD(core_pid, "CORE_PID=%d", current->tgid); + CORE_ENV_ADD(core_uid, "CORE_UID=%d", current->uid); + CORE_ENV_ADD(core_gid, "CORE_GID=%d", current->gid); + CORE_ENV_ADD(core_signal, "CORE_SIGNAL=%ld", signr); + CORE_ENV_ADD(core_comm, "CORE_EXECUTABLE=%s", current->comm); + CORE_ENV_ADD(core_rlim, "CORE_REAL_RLIM=%d", old_rlim); + + do_gettimeofday(&tv); + CORE_ENV_ADD(core_time, "CORE_TIME=%lu", tv.tv_sec); + + down_read(&uts_sem); + CORE_ENV_ADD(core_hostname, "CORE_HOSTNAME=%s", utsname()->nodename); + up_read(&uts_sem); + +#undef CORE_ENV_ADD + + core_envp[i] = NULL; + + core_argv[0] = corename+1; + core_argv[1] = NULL; + /* SIGPIPE can happen, but it's just never processed */ - if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { + if (call_usermodehelper_pipe(core_argv[0], core_argv, + core_envp, &file, &sub_info)) { printk(KERN_INFO "Core dump to %s pipe failed\n", corename); goto fail_unlock; @@ -1554,18 +1617,25 @@ inode = file->f_path.dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ - if (!ispipe && d_unhashed(file->f_path.dentry)) + if (!sub_info && d_unhashed(file->f_path.dentry)) goto close_fail; /* AK: actually i see no reason to not allow this for named pipes etc., but keep the previous behaviour for now. */ - if (!ispipe && !S_ISREG(inode->i_mode)) + if (!sub_info && !S_ISREG(inode->i_mode)) + goto close_fail; + /* + * Dont allow local users get cute and trick others to coredump + * into their pre-created files: + */ + if (inode->i_uid != current->fsuid) goto close_fail; if (!file->f_op) goto close_fail; if (!file->f_op->write) goto close_fail; - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) + if (!sub_info && + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file); @@ -1574,9 +1644,13 @@ current->signal->group_exit_code |= 0x80; close_fail: filp_close(file, NULL); + if (sub_info) + finish_usermodehelper_pipe(sub_info); fail_unlock: current->fsuid = fsuid; complete_all(&mm->core_done); + if (old_rlim >= 0) + current->signal->rlim[RLIMIT_CORE].rlim_cur = old_rlim; fail: return retval; } --- linux-source-2.6.22-2.6.22.orig/fs/ecryptfs/inode.c +++ linux-source-2.6.22-2.6.22/fs/ecryptfs/inode.c @@ -280,7 +280,9 @@ int rc = 0; struct dentry *lower_dir_dentry; struct dentry *lower_dentry; + struct dentry *dentry_save; struct vfsmount *lower_mnt; + struct vfsmount *mnt_save; char *encoded_name; unsigned int encoded_namelen; struct ecryptfs_crypt_stat *crypt_stat = NULL; @@ -308,9 +310,13 @@ } ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " "= [%d]\n", encoded_name, encoded_namelen); - lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, - encoded_namelen - 1); + dentry_save = nd->dentry; + mnt_save = nd->mnt; + lower_dentry = lookup_one_len_nd(encoded_name, lower_dir_dentry, + (encoded_namelen - 1), nd); kfree(encoded_name); + nd->mnt = mnt_save; + nd->dentry = dentry_save; if (IS_ERR(lower_dentry)) { ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); rc = PTR_ERR(lower_dentry); @@ -411,19 +417,24 @@ struct dentry *new_dentry) { struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_dir_dentry; u64 file_size_save; int rc; file_size_save = i_size_read(old_dentry->d_inode); lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); - rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, - lower_new_dentry); + rc = vfs_link(lower_old_dentry, lower_old_mnt, + lower_dir_dentry->d_inode, lower_new_dentry, + lower_new_mnt); if (rc || !lower_new_dentry->d_inode) goto out_lock; rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); @@ -448,10 +459,11 @@ { int rc = 0; struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); lock_parent(lower_dentry); - rc = vfs_unlink(lower_dir_inode, lower_dentry); + rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt); if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); goto out_unlock; @@ -470,6 +482,7 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; umode_t mode; char *encoded_symname; @@ -478,6 +491,7 @@ lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); mode = S_IALLUGO; encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, @@ -487,7 +501,7 @@ rc = encoded_symlen; goto out_lock; } - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, encoded_symname, mode); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) @@ -509,11 +523,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); + rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, + mode); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -532,14 +549,16 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; int rc; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); dget(dentry); lower_dir_dentry = lock_parent(lower_dentry); dget(lower_dentry); - rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt); dput(lower_dentry); if (!rc) d_delete(lower_dentry); @@ -557,11 +576,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); + rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode, + dev); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -582,24 +604,29 @@ { int rc; struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_old_dir_dentry; struct dentry *lower_new_dir_dentry; lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_old_dir_dentry = dget_parent(lower_old_dentry); lower_new_dir_dentry = dget_parent(lower_new_dentry); lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, - lower_new_dir_dentry->d_inode, lower_new_dentry); + lower_old_mnt, lower_new_dir_dentry->d_inode, + lower_new_dentry, lower_new_mnt); if (rc) goto out_lock; - fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); + fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); if (new_dir != old_dir) - fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL); + fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); dput(lower_new_dentry->d_parent); @@ -889,6 +916,7 @@ { int rc = 0; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct inode *inode; struct inode *lower_inode; struct ecryptfs_crypt_stat *crypt_stat; @@ -899,11 +927,13 @@ inode = dentry->d_inode; lower_inode = ecryptfs_inode_to_lower(inode); lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); mutex_lock(&crypt_stat->cs_mutex); if (S_ISDIR(dentry->d_inode->i_mode)) crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); - else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) - || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { + else if (S_ISREG(dentry->d_inode->i_mode) + && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) + || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) { struct vfsmount *lower_mnt; struct file *lower_file = NULL; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; @@ -954,9 +984,9 @@ if (rc < 0) goto out; } - rc = notify_change(lower_dentry, ia); + rc = notify_change(lower_dentry, lower_mnt, ia); out: - fsstack_copy_attr_all(inode, lower_inode, NULL); + fsstack_copy_attr_all(inode, lower_inode); return rc; } --- linux-source-2.6.22-2.6.22.orig/fs/ecryptfs/dentry.c +++ linux-source-2.6.22-2.6.22/fs/ecryptfs/dentry.c @@ -62,7 +62,7 @@ struct inode *lower_inode = ecryptfs_inode_to_lower(dentry->d_inode); - fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL); + fsstack_copy_attr_all(dentry->d_inode, lower_inode); } out: return rc; --- linux-source-2.6.22-2.6.22.orig/fs/ecryptfs/main.c +++ linux-source-2.6.22-2.6.22/fs/ecryptfs/main.c @@ -151,7 +151,7 @@ d_add(dentry, inode); else d_instantiate(dentry, inode); - fsstack_copy_attr_all(inode, lower_inode, NULL); + fsstack_copy_attr_all(inode, lower_inode); /* This size will be overwritten for real files w/ headers and * other metadata */ fsstack_copy_inode_size(inode, lower_inode); --- linux-source-2.6.22-2.6.22.orig/fs/sysfs/file.c +++ linux-source-2.6.22-2.6.22/fs/sysfs/file.c @@ -283,6 +283,7 @@ mutex_lock(&inode->i_mutex); if (!(set = inode->i_private)) { if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) { + mutex_unlock(&inode->i_mutex); error = -ENOMEM; goto Done; } else { @@ -554,7 +555,7 @@ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - res = notify_change(victim, &newattrs); + res = notify_change(victim, NULL, &newattrs); mutex_unlock(&inode->i_mutex); } dput(victim); --- linux-source-2.6.22-2.6.22.orig/fs/namespace.c +++ linux-source-2.6.22-2.6.22/fs/namespace.c @@ -37,7 +37,8 @@ static struct list_head *mount_hashtable __read_mostly; static int hash_mask __read_mostly, hash_bits __read_mostly; static struct kmem_cache *mnt_cache __read_mostly; -static struct rw_semaphore namespace_sem; +struct rw_semaphore namespace_sem; +EXPORT_SYMBOL_GPL(namespace_sem); /* /sys/fs */ decl_subsys(fs, NULL, NULL); @@ -1868,3 +1869,30 @@ release_mounts(&umount_list); kfree(ns); } + +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + struct vfsmount *rootmnt, *nsrootmnt = NULL; + struct dentry *root = NULL; + char *res; + + read_lock(¤t->fs->lock); + rootmnt = mntget(current->fs->rootmnt); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); + if (rootmnt->mnt_ns) + nsrootmnt = mntget(rootmnt->mnt_ns->root); + spin_unlock(&vfsmount_lock); + mntput(rootmnt); + if (nsrootmnt) + root = dget(nsrootmnt->mnt_root); + res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1); + dput(root); + mntput(nsrootmnt); + /* Prevent empty path for lazily unmounted filesystems. */ + if (!IS_ERR(res) && *res == '\0') + *--res = '.'; + return res; +} +EXPORT_SYMBOL(d_namespace_path); --- linux-source-2.6.22-2.6.22.orig/fs/ocfs2/file.c +++ linux-source-2.6.22-2.6.22/fs/ocfs2/file.c @@ -1353,7 +1353,7 @@ else src_page = ERR_PTR(-EFAULT); } else { - bp->b_src_buf = buf; + bp->b_src_buf = (char *)((unsigned long)buf & PAGE_CACHE_MASK); } return src_page; --- linux-source-2.6.22-2.6.22.orig/fs/nfs/inode.c +++ linux-source-2.6.22-2.6.22/fs/nfs/inode.c @@ -961,8 +961,8 @@ goto out_changed; server = NFS_SERVER(inode); - /* Update the fsid if and only if this is the root directory */ - if (inode == inode->i_sb->s_root->d_inode + /* Update the fsid? */ + if (S_ISDIR(inode->i_mode) && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) server->fsid = fattr->fsid; --- linux-source-2.6.22-2.6.22.orig/fs/nfs/write.c +++ linux-source-2.6.22-2.6.22/fs/nfs/write.c @@ -710,6 +710,17 @@ } /* + * If the page cache is marked as unsafe or invalid, then we can't rely on + * the PageUptodate() flag. In this case, we will need to turn off + * write optimisations that depend on the page contents being correct. + */ +static int nfs_write_pageuptodate(struct page *page, struct inode *inode) +{ + return PageUptodate(page) && + !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); +} + +/* * Update and possibly write a cached page of an NFS file. * * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad @@ -730,10 +741,13 @@ (long long)(page_offset(page) +offset)); /* If we're not using byte range locks, and we know the page - * is entirely in cache, it may be more efficient to avoid - * fragmenting write requests. + * is up to date, it may be more efficient to extend the write + * to cover the entire page in order to avoid fragmentation + * inefficiencies. */ - if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { + if (nfs_write_pageuptodate(page, inode) && + inode->i_flock == NULL && + !(file->f_mode & O_SYNC)) { count = max(count + offset, nfs_page_length(page)); offset = 0; } --- linux-source-2.6.22-2.6.22.orig/fs/nfs/getroot.c +++ linux-source-2.6.22-2.6.22/fs/nfs/getroot.c @@ -175,6 +175,9 @@ path++; name.len = path - (const char *) name.name; + if (name.len > NFS4_MAXNAMLEN) + return -ENAMETOOLONG; + eat_dot_dir: while (*path == '/') path++; --- linux-source-2.6.22-2.6.22.orig/fs/nfs/client.c +++ linux-source-2.6.22-2.6.22/fs/nfs/client.c @@ -433,9 +433,6 @@ */ static void nfs_destroy_server(struct nfs_server *server) { - if (!IS_ERR(server->client_acl)) - rpc_shutdown_client(server->client_acl); - if (!(server->flags & NFS_MOUNT_NONLM)) lockd_down(); /* release rpc.lockd */ } @@ -445,6 +442,7 @@ */ static int nfs_start_lockd(struct nfs_server *server) { + static int warned; int error = 0; if (server->nfs_client->cl_nfsversion > 3) @@ -453,9 +451,28 @@ goto out; error = lockd_up((server->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP); - if (error < 0) + if (error < 0) { + /* + * Ubuntu: fix NFS mounting regression from Edgy->Feisty. + * In 2.6.18 and older kernels any failures to start lockd were + * ignored. This meant an Edgy user could successfully mount + * NFS filesystems without having installed nfs-common. + * + * This behaviour has been changed in 2.6.19 and later kernels, + * and so mounting NFS filesystems without nfs-common fail with + * can't read superblock. + * + * This workaround fixes this by issuing a warning (on the first + * lockd start failure), and then allowing the mount to continue + * without locking. + */ + if (warned++ == 0) { + printk(KERN_ERR "nfs: Starting lockd failed (do you have nfs-common installed?).\n"); + printk(KERN_ERR "nfs: Continuing anyway, but this workaround will go away soon.\n"); + } server->flags |= NFS_MOUNT_NONLM; - else + error = 0; + } else server->destroy = nfs_destroy_server; out: return error; @@ -614,16 +631,6 @@ server->namelen = data->namlen; /* Create a client RPC handle for the NFSv3 ACL management interface */ nfs_init_server_aclclient(server); - if (clp->cl_nfsversion == 3) { - if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) - server->namelen = NFS3_MAXNAMLEN; - if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) - server->caps |= NFS_CAP_READDIRPLUS; - } else { - if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) - server->namelen = NFS2_MAXNAMLEN; - } - dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp); return 0; @@ -781,6 +788,9 @@ if (server->destroy != NULL) server->destroy(server); + + if (!IS_ERR(server->client_acl)) + rpc_shutdown_client(server->client_acl); if (!IS_ERR(server->client)) rpc_shutdown_client(server->client); @@ -820,6 +830,16 @@ error = nfs_probe_fsinfo(server, mntfh, &fattr); if (error < 0) goto error; + if (server->nfs_client->rpc_ops->version == 3) { + if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) + server->namelen = NFS3_MAXNAMLEN; + if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) + server->caps |= NFS_CAP_READDIRPLUS; + } else { + if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) + server->namelen = NFS2_MAXNAMLEN; + } + if (!(fattr.valid & NFS_ATTR_FATTR)) { error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr); if (error < 0) { @@ -1010,6 +1030,9 @@ if (error < 0) goto error; + if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) + server->namelen = NFS4_MAXNAMLEN; + BUG_ON(!server->nfs_client); BUG_ON(!server->nfs_client->rpc_ops); BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); @@ -1082,6 +1105,9 @@ if (error < 0) goto error; + if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) + server->namelen = NFS4_MAXNAMLEN; + dprintk("Referral FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, (unsigned long long) server->fsid.minor); @@ -1141,6 +1167,9 @@ if (error < 0) goto out_free_server; + if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) + server->namelen = NFS4_MAXNAMLEN; + dprintk("Cloned FSID: %llx:%llx\n", (unsigned long long) server->fsid.major, (unsigned long long) server->fsid.minor); --- linux-source-2.6.22-2.6.22.orig/fs/nfs/super.c +++ linux-source-2.6.22-2.6.22/fs/nfs/super.c @@ -181,8 +181,8 @@ remove_shrinker(acl_shrinker); #ifdef CONFIG_NFS_V4 unregister_filesystem(&nfs4_fs_type); - nfs_unregister_sysctl(); #endif + nfs_unregister_sysctl(); unregister_filesystem(&nfs_fs_type); } @@ -584,27 +584,71 @@ nfs_initialise_sb(sb); } -static int nfs_set_super(struct super_block *s, void *_server) -{ - struct nfs_server *server = _server; - int ret; +#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS) - s->s_fs_info = server; - ret = set_anon_super(s, server); - if (ret == 0) - server->s_dev = s->s_dev; - return ret; +static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) +{ + const struct nfs_server *a = s->s_fs_info; + const struct rpc_clnt *clnt_a = a->client; + const struct rpc_clnt *clnt_b = b->client; + + if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK)) + goto Ebusy; + if (a->nfs_client != b->nfs_client) + goto Ebusy; + if (a->flags != b->flags) + goto Ebusy; + if (a->wsize != b->wsize) + goto Ebusy; + if (a->rsize != b->rsize) + goto Ebusy; + if (a->acregmin != b->acregmin) + goto Ebusy; + if (a->acregmax != b->acregmax) + goto Ebusy; + if (a->acdirmin != b->acdirmin) + goto Ebusy; + if (a->acdirmax != b->acdirmax) + goto Ebusy; + if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor) + goto Ebusy; + return 1; +Ebusy: + return 0; +} + +struct nfs_sb_mountdata { + struct nfs_server *server; + int mntflags; +}; + +static int nfs_set_super(struct super_block *s, void *data) +{ + struct nfs_sb_mountdata *sb_mntdata = data; + struct nfs_server *server = sb_mntdata->server; + int ret; + + s->s_flags = sb_mntdata->mntflags; + s->s_fs_info = server; + ret = set_anon_super(s, server); + if (ret == 0) + server->s_dev = s->s_dev; + return ret; } static int nfs_compare_super(struct super_block *sb, void *data) { - struct nfs_server *server = data, *old = NFS_SB(sb); - - if (old->nfs_client != server->nfs_client) - return 0; - if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) - return 0; - return 1; + struct nfs_sb_mountdata *sb_mntdata = data; + struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb); + int mntflags = sb_mntdata->mntflags; + + if (memcmp(&old->nfs_client->cl_addr, + &server->nfs_client->cl_addr, + sizeof(old->nfs_client->cl_addr)) != 0) + return 0; + if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) + return 0; + return nfs_compare_mount_options(sb, server, mntflags); } static int nfs_get_sb(struct file_system_type *fs_type, @@ -615,6 +659,9 @@ struct nfs_fh mntfh; struct nfs_mount_data *data = raw_data; struct dentry *mntroot; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; /* Validate the mount data */ @@ -629,8 +676,10 @@ goto out_err_noserver; } + sb_mntdata.server = server; + /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(fs_type, nfs_compare_super, nfs_set_super, server); + s = sget(fs_type, nfs_compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -643,7 +692,6 @@ if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs_fill_super(s, data); } @@ -691,6 +739,9 @@ struct super_block *s; struct nfs_server *server; struct dentry *mntroot; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs_xdev_get_sb()\n"); @@ -701,9 +752,10 @@ error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -716,7 +768,6 @@ if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs_clone_super(s, data->sb); } @@ -808,6 +859,9 @@ struct dentry *mntroot; char *mntpath = NULL, *hostname = NULL, ip_addr[16]; void *p; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; if (data == NULL) { @@ -878,9 +932,10 @@ error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(fs_type, nfs_compare_super, nfs_set_super, server); + s = sget(fs_type, nfs_compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_free; @@ -893,7 +948,6 @@ if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_fill_super(s); } @@ -949,6 +1003,9 @@ struct super_block *s; struct nfs_server *server; struct dentry *mntroot; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs4_xdev_get_sb()\n"); @@ -959,9 +1016,10 @@ error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -974,7 +1032,6 @@ if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_clone_super(s, data->sb); } @@ -1016,6 +1073,9 @@ struct nfs_server *server; struct dentry *mntroot; struct nfs_fh mntfh; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs4_referral_get_sb()\n"); @@ -1026,9 +1086,10 @@ error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -1041,7 +1102,6 @@ if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_fill_super(s); } --- linux-source-2.6.22-2.6.22.orig/fs/nfs/dir.c +++ linux-source-2.6.22-2.6.22/fs/nfs/dir.c @@ -897,14 +897,13 @@ return (nd->intent.open.flags & O_EXCL) != 0; } -static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir, - struct nfs_fh *fh, struct nfs_fattr *fattr) +static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr) { struct nfs_server *server = NFS_SERVER(dir); if (!nfs_fsid_equal(&server->fsid, &fattr->fsid)) - /* Revalidate fsid on root dir */ - return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode); + /* Revalidate fsid using the parent directory */ + return __nfs_revalidate_inode(server, dir); return 0; } @@ -946,7 +945,7 @@ res = ERR_PTR(error); goto out_unlock; } - error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr); + error = nfs_reval_fsid(dir, &fattr); if (error < 0) { res = ERR_PTR(error); goto out_unlock; @@ -1163,6 +1162,8 @@ } if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) return NULL; + if (name.len > NFS_SERVER(dir)->namelen) + return NULL; /* Note: caller is already holding the dir->i_mutex! */ dentry = d_alloc(parent, &name); if (dentry == NULL) --- linux-source-2.6.22-2.6.22.orig/fs/attr.c +++ linux-source-2.6.22-2.6.22/fs/attr.c @@ -100,7 +100,8 @@ } EXPORT_SYMBOL(inode_setattr); -int notify_change(struct dentry * dentry, struct iattr * attr) +int notify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) { struct inode *inode = dentry->d_inode; mode_t mode; @@ -143,13 +144,13 @@ down_write(&dentry->d_inode->i_alloc_sem); if (inode->i_op && inode->i_op->setattr) { - error = security_inode_setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); if (!error) error = inode->i_op->setattr(dentry, attr); } else { error = inode_change_ok(inode, attr); if (!error) - error = security_inode_setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); if (!error) { if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) --- linux-source-2.6.22-2.6.22.orig/fs/jbd/commit.c +++ linux-source-2.6.22-2.6.22/fs/jbd/commit.c @@ -887,7 +887,8 @@ journal->j_committing_transaction = NULL; spin_unlock(&journal->j_state_lock); - if (commit_transaction->t_checkpoint_list == NULL) { + if (commit_transaction->t_checkpoint_list == NULL && + commit_transaction->t_checkpoint_io_list == NULL) { __journal_drop_transaction(journal, commit_transaction); } else { if (journal->j_checkpoint_transactions == NULL) { --- linux-source-2.6.22-2.6.22.orig/fs/drop_caches.c +++ linux-source-2.6.22-2.6.22/fs/drop_caches.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -12,7 +13,7 @@ /* A global variable is a bit ugly, but it keeps the code simple */ int sysctl_drop_caches; -static void drop_pagecache_sb(struct super_block *sb) +void drop_pagecache_sb(struct super_block *sb) { struct inode *inode; @@ -24,6 +25,7 @@ } spin_unlock(&inode_lock); } +EXPORT_SYMBOL(drop_pagecache_sb); void drop_pagecache(void) { --- linux-source-2.6.22-2.6.22.orig/fs/minix/itree_v2.c +++ linux-source-2.6.22-2.6.22/fs/minix/itree_v2.c @@ -23,12 +23,17 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) { int n = 0; + char b[BDEVNAME_SIZE]; struct super_block *sb = inode->i_sb; if (block < 0) { - printk("minix_bmap: block<0\n"); + printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n", + block, bdevname(sb->s_bdev, b)); } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) { - printk("minix_bmap: block>big\n"); + if (printk_ratelimit()) + printk("MINIX-fs: block_to_path: " + "block %ld too big on dev %s\n", + block, bdevname(sb->s_bdev, b)); } else if (block < 7) { offsets[n++] = block; } else if ((block -= 7) < 256) { --- linux-source-2.6.22-2.6.22.orig/fs/minix/itree_v1.c +++ linux-source-2.6.22-2.6.22/fs/minix/itree_v1.c @@ -23,11 +23,16 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) { int n = 0; + char b[BDEVNAME_SIZE]; if (block < 0) { - printk("minix_bmap: block<0\n"); + printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n", + block, bdevname(inode->i_sb->s_bdev, b)); } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { - printk("minix_bmap: block>big\n"); + if (printk_ratelimit()) + printk("MINIX-fs: block_to_path: " + "block %ld too big on dev %s\n", + block, bdevname(inode->i_sb->s_bdev, b)); } else if (block < 7) { offsets[n++] = block; } else if ((block -= 7) < 512) { --- linux-source-2.6.22-2.6.22.orig/fs/namei.c +++ linux-source-2.6.22-2.6.22/fs/namei.c @@ -296,7 +296,13 @@ */ int file_permission(struct file *file, int mask) { - return permission(file->f_path.dentry->d_inode, mask, NULL); + struct nameidata nd; + + nd.dentry = file->f_path.dentry; + nd.mnt = file->f_path.mnt; + nd.flags = LOOKUP_ACCESS; + + return permission(nd.dentry->d_inode, mask, &nd); } /* @@ -487,7 +493,14 @@ */ result = d_lookup(parent, name); if (!result) { - struct dentry * dentry = d_alloc(parent, name); + struct dentry *dentry; + + /* Don't create child dentry for a dead directory. */ + result = ERR_PTR(-ENOENT); + if (IS_DEADDIR(dir)) + goto out_unlock; + + dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); if (dentry) { result = dir->i_op->lookup(dir, dentry, nd); @@ -496,6 +509,7 @@ else result = dentry; } +out_unlock: mutex_unlock(&dir->i_mutex); return result; } @@ -1124,31 +1138,34 @@ nd->mnt = mntget(fs->rootmnt); nd->dentry = dget(fs->root); read_unlock(&fs->lock); + } else if (flags & LOOKUP_ONE) { + /* nd->mnt and nd->dentry already set, just grab references */ + mntget(nd->mnt); + dget(nd->dentry); } else if (dfd == AT_FDCWD) { read_lock(&fs->lock); nd->mnt = mntget(fs->pwdmnt); nd->dentry = dget(fs->pwd); read_unlock(&fs->lock); } else { - struct dentry *dentry; - file = fget_light(dfd, &fput_needed); retval = -EBADF; if (!file) goto out_fail; - dentry = file->f_path.dentry; + nd->dentry = file->f_path.dentry; + nd->mnt = file->f_path.mnt; retval = -ENOTDIR; - if (!S_ISDIR(dentry->d_inode->i_mode)) + if (!S_ISDIR(nd->dentry->d_inode->i_mode)) goto fput_fail; - retval = file_permission(file, MAY_EXEC); + retval = vfs_permission(nd, MAY_EXEC); if (retval) goto fput_fail; - nd->mnt = mntget(file->f_path.mnt); - nd->dentry = dget(dentry); + mntget(nd->mnt); + dget(nd->dentry); fput_light(file, fput_needed); } @@ -1261,7 +1278,14 @@ dentry = cached_lookup(base, name, nd); if (!dentry) { - struct dentry *new = d_alloc(base, name); + struct dentry *new; + + /* Don't create child dentry for a dead directory. */ + dentry = ERR_PTR(-ENOENT); + if (IS_DEADDIR(inode)) + goto out; + + new = d_alloc(base, name); dentry = ERR_PTR(-ENOMEM); if (!new) goto out; @@ -1325,7 +1349,8 @@ return 0; } -struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) +struct dentry *lookup_one_len_nd(const char *name, struct dentry *base, + int len, struct nameidata *nd) { int err; struct qstr this; @@ -1333,7 +1358,7 @@ err = __lookup_one_len(name, &this, base, len); if (err) return ERR_PTR(err); - return __lookup_hash(&this, base, NULL); + return __lookup_hash(&this, base, nd); } struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int len) @@ -1409,6 +1434,10 @@ BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(victim->d_name.name, victim->d_inode, dir); +#if 0 + if (nd) + nd->flags |= LOOKUP_CONTINUE; +#endif error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); if (error) return error; @@ -1446,6 +1475,8 @@ return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; + if (nd) + nd->flags |= LOOKUP_CONTINUE; return permission(dir,MAY_WRITE | MAY_EXEC, nd); } @@ -1521,7 +1552,7 @@ return -EACCES; /* shouldn't it be ENOSYS? */ mode &= S_IALLUGO; mode |= S_IFREG; - error = security_inode_create(dir, dentry, mode); + error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode); if (error) return error; DQUOT_INIT(dir); @@ -1543,7 +1574,7 @@ if (S_ISLNK(inode->i_mode)) return -ELOOP; - if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) + if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) return -EISDIR; error = vfs_permission(nd, acc_mode); @@ -1562,7 +1593,7 @@ return -EACCES; flag &= ~O_TRUNC; - } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE)) + } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE)) return -EROFS; /* * An append-only file must be opened in append mode for writing. @@ -1598,7 +1629,8 @@ if (!error) { DQUOT_INIT(inode); - error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL); + error = do_truncate(dentry, nd->mnt, 0, + ATTR_MTIME|ATTR_CTIME, NULL); } put_write_access(inode); if (error) @@ -1854,7 +1886,8 @@ } EXPORT_SYMBOL_GPL(lookup_create); -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode, dev_t dev) { int error = may_create(dir, dentry, NULL); @@ -1867,7 +1900,7 @@ if (!dir->i_op || !dir->i_op->mknod) return -EPERM; - error = security_inode_mknod(dir, dentry, mode, dev); + error = security_inode_mknod(dir, dentry, mnt, mode, dev); if (error) return error; @@ -1906,11 +1939,12 @@ error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.dentry->d_inode,dentry,mode, - new_decode_dev(dev)); + error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, + mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, + mode, 0); break; case S_IFDIR: error = -EPERM; @@ -1933,7 +1967,8 @@ return sys_mknodat(AT_FDCWD, filename, mode, dev); } -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode) { int error = may_create(dir, dentry, NULL); @@ -1944,7 +1979,7 @@ return -EPERM; mode &= (S_IRWXUGO|S_ISVTX); - error = security_inode_mkdir(dir, dentry, mode); + error = security_inode_mkdir(dir, dentry, mnt, mode); if (error) return error; @@ -1977,7 +2012,7 @@ if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.dentry->d_inode, dentry, nd.mnt, mode); dput(dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2020,7 +2055,7 @@ spin_unlock(&dcache_lock); } -int vfs_rmdir(struct inode *dir, struct dentry *dentry) +int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt) { int error = may_delete(dir, dentry, 1); @@ -2030,6 +2065,10 @@ if (!dir->i_op || !dir->i_op->rmdir) return -EPERM; + error = security_inode_rmdir(dir, dentry, mnt); + if (error) + return error; + DQUOT_INIT(dir); mutex_lock(&dentry->d_inode->i_mutex); @@ -2037,12 +2076,9 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_rmdir(dir, dentry); - if (!error) { - error = dir->i_op->rmdir(dir, dentry); - if (!error) - dentry->d_inode->i_flags |= S_DEAD; - } + error = dir->i_op->rmdir(dir, dentry); + if (!error) + dentry->d_inode->i_flags |= S_DEAD; } mutex_unlock(&dentry->d_inode->i_mutex); if (!error) { @@ -2084,7 +2120,7 @@ error = PTR_ERR(dentry); if (IS_ERR(dentry)) goto exit2; - error = vfs_rmdir(nd.dentry->d_inode, dentry); + error = vfs_rmdir(nd.dentry->d_inode, dentry, nd.mnt); dput(dentry); exit2: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2100,7 +2136,7 @@ return do_rmdir(AT_FDCWD, pathname); } -int vfs_unlink(struct inode *dir, struct dentry *dentry) +int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt) { int error = may_delete(dir, dentry, 0); @@ -2116,7 +2152,7 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_unlink(dir, dentry); + error = security_inode_unlink(dir, dentry, mnt); if (!error) error = dir->i_op->unlink(dir, dentry); } @@ -2164,7 +2200,7 @@ inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); - error = vfs_unlink(nd.dentry->d_inode, dentry); + error = vfs_unlink(nd.dentry->d_inode, dentry, nd.mnt); exit2: dput(dentry); } @@ -2199,7 +2235,8 @@ return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) +int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + const char *oldname, int mode) { int error = may_create(dir, dentry, NULL); @@ -2209,7 +2246,7 @@ if (!dir->i_op || !dir->i_op->symlink) return -EPERM; - error = security_inode_symlink(dir, dentry, oldname); + error = security_inode_symlink(dir, dentry, mnt, oldname); if (error) return error; @@ -2245,7 +2282,8 @@ if (IS_ERR(dentry)) goto out_unlock; - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); + error = vfs_symlink(nd.dentry->d_inode, dentry, nd.mnt, from, + S_IALLUGO); dput(dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2262,7 +2300,7 @@ return sys_symlinkat(oldname, AT_FDCWD, newname); } -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *inode = old_dentry->d_inode; int error; @@ -2287,7 +2325,8 @@ if (S_ISDIR(old_dentry->d_inode->i_mode)) return -EPERM; - error = security_inode_link(old_dentry, dir, new_dentry); + error = security_inode_link(old_dentry, old_mnt, dir, new_dentry, + new_mnt); if (error) return error; @@ -2340,7 +2379,8 @@ error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) goto out_unlock; - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); + error = vfs_link(old_nd.dentry, old_nd.mnt, nd.dentry->d_inode, + new_dentry, nd.mnt); dput(new_dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); @@ -2392,7 +2432,8 @@ * locking]. */ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error = 0; struct inode *target; @@ -2407,7 +2448,8 @@ return error; } - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2435,12 +2477,14 @@ } static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *target; int error; - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2463,7 +2507,8 @@ } int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error; int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); @@ -2492,9 +2537,11 @@ old_name = fsnotify_oldname_init(old_dentry->d_name.name); if (is_dir) - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_dir(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); else - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_other(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (!error) { const char *new_name = old_dentry->d_name.name; fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, @@ -2566,8 +2613,8 @@ if (new_dentry == trap) goto exit5; - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); + error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.mnt, + new_dir->d_inode, new_dentry, newnd.mnt); exit5: dput(new_dentry); exit4: @@ -2766,7 +2813,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ EXPORT_SYMBOL(getname); EXPORT_SYMBOL(lock_rename); -EXPORT_SYMBOL(lookup_one_len); +EXPORT_SYMBOL(lookup_one_len_nd); EXPORT_SYMBOL(page_follow_link_light); EXPORT_SYMBOL(page_put_link); EXPORT_SYMBOL(page_readlink); --- linux-source-2.6.22-2.6.22.orig/fs/utimes.c +++ linux-source-2.6.22-2.6.22/fs/utimes.c @@ -38,6 +38,19 @@ #endif +static bool nsec_special(long nsec) +{ + return nsec == UTIME_OMIT || nsec == UTIME_NOW; +} + +static bool nsec_valid(long nsec) +{ + if (nsec_special(nsec)) + return true; + + return nsec >= 0 && nsec <= 999999999; +} + /* If times==NULL, set access and modification to current time, * must be owner or have write permission. * Else, update from *times, must be owner or super user. @@ -46,12 +59,17 @@ { int error; struct nameidata nd; - struct dentry *dentry; + struct path path; struct inode *inode; struct iattr newattrs; struct file *f = NULL; error = -EINVAL; + if (times && (!nsec_valid(times[0].tv_nsec) || + !nsec_valid(times[1].tv_nsec))) { + goto out; + } + if (flags & ~AT_SYMLINK_NOFOLLOW) goto out; @@ -64,16 +82,17 @@ f = fget(dfd); if (!f) goto out; - dentry = f->f_path.dentry; + path = f->f_path; } else { error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); if (error) goto out; - dentry = nd.dentry; + path.dentry = nd.dentry; + path.mnt = nd.mnt; } - inode = dentry->d_inode; + inode = path.dentry->d_inode; error = -EROFS; if (IS_RDONLY(inode)) @@ -101,7 +120,15 @@ newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } - } else { + } + + /* + * If times is NULL or both times are either UTIME_OMIT or + * UTIME_NOW, then need to check permissions, because + * inode_change_ok() won't do it. + */ + if (!times || (nsec_special(times[0].tv_nsec) && + nsec_special(times[1].tv_nsec))) { error = -EACCES; if (IS_IMMUTABLE(inode)) goto dput_and_out; @@ -118,7 +145,7 @@ } } mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = notify_change(path.dentry, path.mnt, &newattrs); mutex_unlock(&inode->i_mutex); dput_and_out: if (f) --- linux-source-2.6.22-2.6.22.orig/fs/ext3/namei.c +++ linux-source-2.6.22-2.6.22/fs/ext3/namei.c @@ -140,7 +140,8 @@ struct dx_map_entry { u32 hash; - u32 offs; + u16 offs; + u16 size; }; #ifdef CONFIG_EXT3_INDEX @@ -379,13 +380,28 @@ entries = (struct dx_entry *) (((char *)&root->info) + root->info.info_length); - assert(dx_get_limit(entries) == dx_root_limit(dir, - root->info.info_length)); + + if (dx_get_limit(entries) != dx_root_limit(dir, + root->info.info_length)) { + ext3_warning(dir->i_sb, __FUNCTION__, + "dx entry: limit != root limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail; + } + dxtrace (printk("Look up %x", hash)); while (1) { count = dx_get_count(entries); - assert (count && count <= dx_get_limit(entries)); + if (!count || count > dx_get_limit(entries)) { + ext3_warning(dir->i_sb, __FUNCTION__, + "dx entry: no count or count > limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail2; + } + p = entries + 1; q = entries + count - 1; while (p <= q) @@ -423,8 +439,15 @@ if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) goto fail2; at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); + if (dx_get_limit(entries) != dx_node_limit (dir)) { + ext3_warning(dir->i_sb, __FUNCTION__, + "dx entry: limit != node limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail2; + } frame++; + frame->bh = NULL; } fail2: while (frame >= frame_in) { @@ -432,6 +455,10 @@ frame--; } fail: + if (*err == ERR_BAD_DX_DIR) + ext3_warning(dir->i_sb, __FUNCTION__, + "Corrupt dir inode %ld, running e2fsck is " + "recommended.", dir->i_ino); return NULL; } @@ -671,6 +698,10 @@ * Directory block splitting, compacting */ +/* + * Create map of hash values, offsets, and sizes, stored at end of block. + * Returns number of entries mapped. + */ static int dx_make_map (struct ext3_dir_entry_2 *de, int size, struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) { @@ -684,7 +715,8 @@ ext3fs_dirhash(de->name, de->name_len, &h); map_tail--; map_tail->hash = h.hash; - map_tail->offs = (u32) ((char *) de - base); + map_tail->offs = (u16) ((char *) de - base); + map_tail->size = le16_to_cpu(de->rec_len); count++; cond_resched(); } @@ -694,6 +726,7 @@ return count; } +/* Sort map by hash value */ static void dx_sort_map (struct dx_map_entry *map, unsigned count) { struct dx_map_entry *p, *q, *top = map + count - 1; @@ -1081,6 +1114,10 @@ } #ifdef CONFIG_EXT3_INDEX +/* + * Move count entries from end of map between two memory locations. + * Returns pointer to last entry moved. + */ static struct ext3_dir_entry_2 * dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) { @@ -1099,6 +1136,10 @@ return (struct ext3_dir_entry_2 *) (to - rec_len); } +/* + * Compact each dir entry in the range to the minimal rec_len. + * Returns pointer to last entry in range. + */ static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) { struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; @@ -1121,6 +1162,11 @@ return prev; } +/* + * Split a full leaf block to make room for a new dir entry. + * Allocate a new block, and move entries so that they are approx. equally full. + * Returns pointer to de in block into which the new entry will be inserted. + */ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, struct buffer_head **bh,struct dx_frame *frame, struct dx_hash_info *hinfo, int *error) @@ -1132,7 +1178,7 @@ u32 hash2; struct dx_map_entry *map; char *data1 = (*bh)->b_data, *data2; - unsigned split; + unsigned split, move, size, i; struct ext3_dir_entry_2 *de = NULL, *de2; int err = 0; @@ -1160,8 +1206,19 @@ count = dx_make_map ((struct ext3_dir_entry_2 *) data1, blocksize, hinfo, map); map -= count; - split = count/2; // need to adjust to actual middle dx_sort_map (map, count); + /* Split the existing block in the middle, size-wise */ + size = 0; + move = 0; + for (i = count-1; i >= 0; i--) { + /* is more than half of this entry in 2nd half of the block? */ + if (size + map[i].size/2 > blocksize/2) + break; + size += map[i].size; + move++; + } + /* map index at which we will split */ + split = count - move; hash2 = map[split].hash; continued = hash2 == map[split - 1].hash; dxtrace(printk("Split block %i at %x, %i/%i\n", --- linux-source-2.6.22-2.6.22.orig/fs/dlm/debug_fs.c +++ linux-source-2.6.22-2.6.22/fs/dlm/debug_fs.c @@ -17,6 +17,7 @@ #include #include "dlm_internal.h" +#include "lock.h" #define DLM_DEBUG_BUF_LEN 4096 static char debug_buf[DLM_DEBUG_BUF_LEN]; @@ -26,6 +27,8 @@ struct rsb_iter { int entry; + int master; + int header; struct dlm_ls *ls; struct list_head *next; struct dlm_rsb *rsb; @@ -85,6 +88,8 @@ struct dlm_lkb *lkb; int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list; + lock_rsb(res); + seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length); for (i = 0; i < res->res_length; i++) { if (isprint(res->res_name[i])) @@ -151,6 +156,59 @@ seq_printf(s, "\n"); } out: + unlock_rsb(res); + return 0; +} + +static void print_master_lock(struct seq_file *s, struct dlm_lkb *lkb, + struct dlm_rsb *r) +{ + struct dlm_user_args *ua; + unsigned int waiting = 0; + uint64_t xid = 0; + + if (lkb->lkb_flags & DLM_IFL_USER) { + ua = (struct dlm_user_args *) lkb->lkb_astparam; + if (ua) + xid = ua->xid; + } + + if (lkb->lkb_timestamp) + waiting = jiffies_to_msecs(jiffies - lkb->lkb_timestamp); + + /* id nodeid remid pid xid flags sts grmode rqmode time_ms len name */ + + seq_printf(s, "%x %d %x %u %llu %x %d %d %d %u %d \"%s\"\n", + lkb->lkb_id, + lkb->lkb_nodeid, + lkb->lkb_remid, + lkb->lkb_ownpid, + (unsigned long long)xid, + lkb->lkb_exflags, + lkb->lkb_status, + lkb->lkb_grmode, + lkb->lkb_rqmode, + waiting, + r->res_length, + r->res_name); +} + +static int print_master_resource(struct dlm_rsb *r, struct seq_file *s) +{ + struct dlm_lkb *lkb; + + lock_rsb(r); + + list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) + print_master_lock(s, lkb, r); + + unlock_rsb(r); return 0; } @@ -166,6 +224,9 @@ read_lock(&ls->ls_rsbtbl[i].lock); if (!list_empty(&ls->ls_rsbtbl[i].list)) { ri->next = ls->ls_rsbtbl[i].list.next; + ri->rsb = list_entry(ri->next, struct dlm_rsb, + res_hashchain); + dlm_hold_rsb(ri->rsb); read_unlock(&ls->ls_rsbtbl[i].lock); break; } @@ -176,6 +237,7 @@ if (ri->entry >= ls->ls_rsbtbl_size) return 1; } else { + struct dlm_rsb *old = ri->rsb; i = ri->entry; read_lock(&ls->ls_rsbtbl[i].lock); ri->next = ri->next->next; @@ -184,11 +246,14 @@ ri->next = NULL; ri->entry++; read_unlock(&ls->ls_rsbtbl[i].lock); + dlm_put_rsb(old); goto top; } + ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain); + dlm_hold_rsb(ri->rsb); read_unlock(&ls->ls_rsbtbl[i].lock); + dlm_put_rsb(old); } - ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain); return 0; } @@ -202,7 +267,7 @@ { struct rsb_iter *ri; - ri = kmalloc(sizeof *ri, GFP_KERNEL); + ri = kzalloc(sizeof *ri, GFP_KERNEL); if (!ri) return NULL; @@ -260,7 +325,17 @@ { struct rsb_iter *ri = iter_ptr; - print_resource(ri->rsb, file); + if (ri->master) { + if (ri->header) { + seq_printf(file, "id nodeid remid pid xid flags sts " + "grmode rqmode time_ms len name\n"); + ri->header = 0; + } + if (is_master(ri->rsb)) + print_master_resource(ri->rsb, file); + } else { + print_resource(ri->rsb, file); + } return 0; } @@ -296,6 +371,83 @@ }; /* + * Dump master lock state + */ + +static struct rsb_iter *master_iter_init(struct dlm_ls *ls, loff_t *pos) +{ + struct rsb_iter *ri; + + ri = kzalloc(sizeof *ri, GFP_KERNEL); + if (!ri) + return NULL; + + ri->ls = ls; + ri->entry = 0; + ri->next = NULL; + ri->master = 1; + + if (*pos == 0) + ri->header = 1; + + if (rsb_iter_next(ri)) { + rsb_iter_free(ri); + return NULL; + } + + return ri; +} + +static void *master_seq_start(struct seq_file *file, loff_t *pos) +{ + struct rsb_iter *ri; + loff_t n = *pos; + + ri = master_iter_init(file->private, pos); + if (!ri) + return NULL; + + while (n--) { + if (rsb_iter_next(ri)) { + rsb_iter_free(ri); + return NULL; + } + } + + return ri; +} + +static struct seq_operations master_seq_ops = { + .start = master_seq_start, + .next = rsb_seq_next, + .stop = rsb_seq_stop, + .show = rsb_seq_show, +}; + +static int master_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + int ret; + + ret = seq_open(file, &master_seq_ops); + if (ret) + return ret; + + seq = file->private_data; + seq->private = inode->i_private; + + return 0; +} + +static const struct file_operations master_fops = { + .owner = THIS_MODULE, + .open = master_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + +/* * dump lkb's on the ls_waiters list */ @@ -362,6 +514,20 @@ return -ENOMEM; } + memset(name, 0, sizeof(name)); + snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_master", ls->ls_name); + + ls->ls_debug_master_dentry = debugfs_create_file(name, + S_IFREG | S_IRUGO, + dlm_root, + ls, + &master_fops); + if (!ls->ls_debug_master_dentry) { + debugfs_remove(ls->ls_debug_waiters_dentry); + debugfs_remove(ls->ls_debug_rsb_dentry); + return -ENOMEM; + } + return 0; } @@ -371,6 +537,8 @@ debugfs_remove(ls->ls_debug_rsb_dentry); if (ls->ls_debug_waiters_dentry) debugfs_remove(ls->ls_debug_waiters_dentry); + if (ls->ls_debug_master_dentry) + debugfs_remove(ls->ls_debug_master_dentry); } int dlm_register_debugfs(void) --- linux-source-2.6.22-2.6.22.orig/fs/dlm/lockspace.c +++ linux-source-2.6.22-2.6.22/fs/dlm/lockspace.c @@ -197,13 +197,24 @@ else kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); + log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving"); + + /* dlm_controld will see the uevent, do the necessary group management + and then write to sysfs to wake us */ + error = wait_event_interruptible(ls->ls_uevent_wait, test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); + + log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result); + if (error) goto out; error = ls->ls_uevent_result; out: + if (error) + log_error(ls, "group %s failed %d %d", in ? "join" : "leave", + error, ls->ls_uevent_result); return error; } @@ -234,8 +245,13 @@ struct dlm_ls *ls; while (!kthread_should_stop()) { - list_for_each_entry(ls, &lslist, ls_list) - dlm_scan_rsbs(ls); + list_for_each_entry(ls, &lslist, ls_list) { + if (dlm_lock_recovery_try(ls)) { + dlm_scan_rsbs(ls); + dlm_scan_timeout(ls); + dlm_unlock_recovery(ls); + } + } schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); } return 0; @@ -395,6 +411,7 @@ { struct dlm_ls *ls; int i, size, error = -ENOMEM; + int do_unreg = 0; if (namelen > DLM_LOCKSPACE_LEN) return -EINVAL; @@ -417,11 +434,22 @@ goto out; memcpy(ls->ls_name, name, namelen); ls->ls_namelen = namelen; - ls->ls_exflags = flags; ls->ls_lvblen = lvblen; ls->ls_count = 0; ls->ls_flags = 0; + if (flags & DLM_LSFL_TIMEWARN) + set_bit(LSFL_TIMEWARN, &ls->ls_flags); + + if (flags & DLM_LSFL_FS) + ls->ls_allocation = GFP_NOFS; + else + ls->ls_allocation = GFP_KERNEL; + + /* ls_exflags are forced to match among nodes, and we don't + need to require all nodes to have TIMEWARN or FS set */ + ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS)); + size = dlm_config.ci_rsbtbl_size; ls->ls_rsbtbl_size = size; @@ -461,6 +489,8 @@ mutex_init(&ls->ls_waiters_mutex); INIT_LIST_HEAD(&ls->ls_orphans); mutex_init(&ls->ls_orphans_mutex); + INIT_LIST_HEAD(&ls->ls_timeout); + mutex_init(&ls->ls_timeout_mutex); INIT_LIST_HEAD(&ls->ls_nodes); INIT_LIST_HEAD(&ls->ls_nodes_gone); @@ -477,6 +507,8 @@ init_waitqueue_head(&ls->ls_uevent_wait); ls->ls_uevent_result = 0; + init_completion(&ls->ls_members_done); + ls->ls_members_result = -1; ls->ls_recoverd_task = NULL; mutex_init(&ls->ls_recoverd_active); @@ -513,32 +545,49 @@ error = dlm_recoverd_start(ls); if (error) { log_error(ls, "can't start dlm_recoverd %d", error); - goto out_rcomfree; + goto out_delist; } - dlm_create_debug_file(ls); - error = kobject_setup(ls); if (error) - goto out_del; + goto out_stop; error = kobject_register(&ls->ls_kobj); if (error) - goto out_del; + goto out_stop; + + /* let kobject handle freeing of ls if there's an error */ + do_unreg = 1; + + /* This uevent triggers dlm_controld in userspace to add us to the + group of nodes that are members of this lockspace (managed by the + cluster infrastructure.) Once it's done that, it tells us who the + current lockspace members are (via configfs) and then tells the + lockspace to start running (via sysfs) in dlm_ls_start(). */ error = do_uevent(ls, 1); if (error) - goto out_unreg; + goto out_stop; + + wait_for_completion(&ls->ls_members_done); + error = ls->ls_members_result; + if (error) + goto out_members; + + dlm_create_debug_file(ls); + + log_debug(ls, "join complete"); *lockspace = ls; return 0; - out_unreg: - kobject_unregister(&ls->ls_kobj); - out_del: - dlm_delete_debug_file(ls); + out_members: + do_uevent(ls, 0); + dlm_clear_members(ls); + kfree(ls->ls_node_array); + out_stop: dlm_recoverd_stop(ls); - out_rcomfree: + out_delist: spin_lock(&lslist_lock); list_del(&ls->ls_list); spin_unlock(&lslist_lock); @@ -550,7 +599,10 @@ out_rsbfree: kfree(ls->ls_rsbtbl); out_lsfree: - kfree(ls); + if (do_unreg) + kobject_unregister(&ls->ls_kobj); + else + kfree(ls); out: module_put(THIS_MODULE); return error; @@ -570,6 +622,8 @@ error = new_lockspace(name, namelen, lockspace, flags, lvblen); if (!error) ls_count++; + else if (!ls_count) + threads_stop(); out: mutex_unlock(&ls_lock); return error; @@ -696,7 +750,7 @@ dlm_clear_members_gone(ls); kfree(ls->ls_node_array); kobject_unregister(&ls->ls_kobj); - /* The ls structure will be freed when the kobject is done with */ + /* The ls structure will be freed when the kobject is done with */ mutex_lock(&ls_lock); ls_count--; --- linux-source-2.6.22-2.6.22.orig/fs/dlm/config.c +++ linux-source-2.6.22-2.6.22/fs/dlm/config.c @@ -90,6 +90,7 @@ unsigned int cl_scan_secs; unsigned int cl_log_debug; unsigned int cl_protocol; + unsigned int cl_timewarn_cs; }; enum { @@ -103,6 +104,7 @@ CLUSTER_ATTR_SCAN_SECS, CLUSTER_ATTR_LOG_DEBUG, CLUSTER_ATTR_PROTOCOL, + CLUSTER_ATTR_TIMEWARN_CS, }; struct cluster_attribute { @@ -162,6 +164,7 @@ CLUSTER_ATTR(scan_secs, 1); CLUSTER_ATTR(log_debug, 0); CLUSTER_ATTR(protocol, 0); +CLUSTER_ATTR(timewarn_cs, 1); static struct configfs_attribute *cluster_attrs[] = { [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, @@ -174,6 +177,7 @@ [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr, [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, + [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, NULL, }; @@ -429,6 +433,8 @@ cl->cl_toss_secs = dlm_config.ci_toss_secs; cl->cl_scan_secs = dlm_config.ci_scan_secs; cl->cl_log_debug = dlm_config.ci_log_debug; + cl->cl_protocol = dlm_config.ci_protocol; + cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; space_list = &sps->ss_group; comm_list = &cms->cs_group; @@ -748,9 +754,16 @@ static struct space *get_space(char *name) { + struct config_item *i; + if (!space_list) return NULL; - return to_space(config_group_find_obj(space_list, name)); + + down(&space_list->cg_subsys->su_sem); + i = config_group_find_obj(space_list, name); + up(&space_list->cg_subsys->su_sem); + + return to_space(i); } static void put_space(struct space *sp) @@ -776,20 +789,20 @@ if (cm->nodeid != nodeid) continue; found = 1; + config_item_get(i); break; } else { if (!cm->addr_count || memcmp(cm->addr[0], addr, sizeof(*addr))) continue; found = 1; + config_item_get(i); break; } } up(&clusters_root.subsys.su_sem); - if (found) - config_item_get(i); - else + if (!found) cm = NULL; return cm; } @@ -909,6 +922,7 @@ #define DEFAULT_SCAN_SECS 5 #define DEFAULT_LOG_DEBUG 0 #define DEFAULT_PROTOCOL 0 +#define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ struct dlm_config_info dlm_config = { .ci_tcp_port = DEFAULT_TCP_PORT, @@ -920,6 +934,7 @@ .ci_toss_secs = DEFAULT_TOSS_SECS, .ci_scan_secs = DEFAULT_SCAN_SECS, .ci_log_debug = DEFAULT_LOG_DEBUG, - .ci_protocol = DEFAULT_PROTOCOL + .ci_protocol = DEFAULT_PROTOCOL, + .ci_timewarn_cs = DEFAULT_TIMEWARN_CS }; --- linux-source-2.6.22-2.6.22.orig/fs/dlm/Makefile +++ linux-source-2.6.22-2.6.22/fs/dlm/Makefile @@ -8,6 +8,7 @@ member.o \ memory.o \ midcomms.o \ + netlink.o \ lowcomms.o \ rcom.o \ recover.o \ --- linux-source-2.6.22-2.6.22.orig/fs/dlm/dlm_internal.h +++ linux-source-2.6.22-2.6.22/fs/dlm/dlm_internal.h @@ -151,6 +151,7 @@ void *bastaddr; int mode; struct dlm_lksb *lksb; + unsigned long timeout; }; @@ -213,6 +214,9 @@ #define DLM_IFL_OVERLAP_UNLOCK 0x00080000 #define DLM_IFL_OVERLAP_CANCEL 0x00100000 #define DLM_IFL_ENDOFLIFE 0x00200000 +#define DLM_IFL_WATCH_TIMEWARN 0x00400000 +#define DLM_IFL_TIMEOUT_CANCEL 0x00800000 +#define DLM_IFL_DEADLOCK_CANCEL 0x01000000 #define DLM_IFL_USER 0x00000001 #define DLM_IFL_ORPHAN 0x00000002 @@ -243,6 +247,9 @@ struct list_head lkb_wait_reply; /* waiting for remote reply */ struct list_head lkb_astqueue; /* need ast to be sent */ struct list_head lkb_ownqueue; /* list of locks for a process */ + struct list_head lkb_time_list; + unsigned long lkb_timestamp; + unsigned long lkb_timeout_cs; char *lkb_lvbptr; struct dlm_lksb *lkb_lksb; /* caller's status block */ @@ -447,12 +454,16 @@ struct mutex ls_orphans_mutex; struct list_head ls_orphans; + struct mutex ls_timeout_mutex; + struct list_head ls_timeout; + struct list_head ls_nodes; /* current nodes in ls */ struct list_head ls_nodes_gone; /* dead node list, recovery */ int ls_num_nodes; /* number of nodes in ls */ int ls_low_nodeid; int ls_total_weight; int *ls_node_array; + gfp_t ls_allocation; struct dlm_rsb ls_stub_rsb; /* for returning errors */ struct dlm_lkb ls_stub_lkb; /* for returning errors */ @@ -460,9 +471,12 @@ struct dentry *ls_debug_rsb_dentry; /* debugfs */ struct dentry *ls_debug_waiters_dentry; /* debugfs */ + struct dentry *ls_debug_master_dentry; /* debugfs */ wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ int ls_uevent_result; + struct completion ls_members_done; + int ls_members_result; struct miscdevice ls_device; @@ -472,6 +486,7 @@ struct task_struct *ls_recoverd_task; struct mutex ls_recoverd_active; spinlock_t ls_recover_lock; + unsigned long ls_recover_begin; /* jiffies timestamp */ uint32_t ls_recover_status; /* DLM_RS_ */ uint64_t ls_recover_seq; struct dlm_recover *ls_recover_args; @@ -501,6 +516,7 @@ #define LSFL_RCOM_READY 3 #define LSFL_RCOM_WAIT 4 #define LSFL_UEVENT_WAIT 5 +#define LSFL_TIMEWARN 6 /* much of this is just saving user space pointers associated with the lock that we pass back to the user lib with an ast */ @@ -518,6 +534,7 @@ void __user *castaddr; void __user *bastparam; void __user *bastaddr; + uint64_t xid; }; #define DLM_PROC_FLAGS_CLOSING 1 --- linux-source-2.6.22-2.6.22.orig/fs/dlm/recoverd.c +++ linux-source-2.6.22-2.6.22/fs/dlm/recoverd.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -190,6 +190,8 @@ dlm_clear_members_gone(ls); + dlm_adjust_timeouts(ls); + error = enable_locking(ls, rv->seq); if (error) { log_debug(ls, "enable_locking failed %d", error); --- linux-source-2.6.22-2.6.22.orig/fs/dlm/lock.h +++ linux-source-2.6.22-2.6.22/fs/dlm/lock.h @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -24,6 +24,10 @@ void dlm_hold_rsb(struct dlm_rsb *r); int dlm_put_lkb(struct dlm_lkb *lkb); void dlm_scan_rsbs(struct dlm_ls *ls); +int dlm_lock_recovery_try(struct dlm_ls *ls); +void dlm_unlock_recovery(struct dlm_ls *ls); +void dlm_scan_timeout(struct dlm_ls *ls); +void dlm_adjust_timeouts(struct dlm_ls *ls); int dlm_purge_locks(struct dlm_ls *ls); void dlm_purge_mstcpy_locks(struct dlm_rsb *r); @@ -34,15 +38,18 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc); int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, - uint32_t flags, void *name, unsigned int namelen, uint32_t parent_lkid); + uint32_t flags, void *name, unsigned int namelen, + unsigned long timeout_cs); int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, - int mode, uint32_t flags, uint32_t lkid, char *lvb_in); + int mode, uint32_t flags, uint32_t lkid, char *lvb_in, + unsigned long timeout_cs); int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid, char *lvb_in); int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid); int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc, int nodeid, int pid); +int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid); void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc); static inline int is_master(struct dlm_rsb *r) --- linux-source-2.6.22-2.6.22.orig/fs/dlm/lock.c +++ linux-source-2.6.22-2.6.22/fs/dlm/lock.c @@ -82,10 +82,13 @@ static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb); static int send_remove(struct dlm_rsb *r); static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); +static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, struct dlm_message *ms); static int receive_extralen(struct dlm_message *ms); static void do_purge(struct dlm_ls *ls, int nodeid, int pid); +static void del_timeout(struct dlm_lkb *lkb); +void dlm_timeout_warn(struct dlm_lkb *lkb); /* * Lock compatibilty matrix - thanks Steve @@ -194,17 +197,17 @@ /* Threads cannot use the lockspace while it's being recovered */ -static inline void lock_recovery(struct dlm_ls *ls) +static inline void dlm_lock_recovery(struct dlm_ls *ls) { down_read(&ls->ls_in_recovery); } -static inline void unlock_recovery(struct dlm_ls *ls) +void dlm_unlock_recovery(struct dlm_ls *ls) { up_read(&ls->ls_in_recovery); } -static inline int lock_recovery_try(struct dlm_ls *ls) +int dlm_lock_recovery_try(struct dlm_ls *ls) { return down_read_trylock(&ls->ls_in_recovery); } @@ -286,8 +289,22 @@ if (is_master_copy(lkb)) return; + del_timeout(lkb); + DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb);); + /* if the operation was a cancel, then return -DLM_ECANCEL, if a + timeout caused the cancel then return -ETIMEDOUT */ + if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) { + lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL; + rv = -ETIMEDOUT; + } + + if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_DEADLOCK_CANCEL)) { + lkb->lkb_flags &= ~DLM_IFL_DEADLOCK_CANCEL; + rv = -EDEADLK; + } + lkb->lkb_lksb->sb_status = rv; lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; @@ -581,6 +598,7 @@ kref_init(&lkb->lkb_ref); INIT_LIST_HEAD(&lkb->lkb_ownqueue); INIT_LIST_HEAD(&lkb->lkb_rsb_lookup); + INIT_LIST_HEAD(&lkb->lkb_time_list); get_random_bytes(&bucket, sizeof(bucket)); bucket &= (ls->ls_lkbtbl_size - 1); @@ -985,15 +1003,136 @@ { int i; - if (dlm_locking_stopped(ls)) - return; - for (i = 0; i < ls->ls_rsbtbl_size; i++) { shrink_bucket(ls, i); + if (dlm_locking_stopped(ls)) + break; cond_resched(); } } +static void add_timeout(struct dlm_lkb *lkb) +{ + struct dlm_ls *ls = lkb->lkb_resource->res_ls; + + if (is_master_copy(lkb)) { + lkb->lkb_timestamp = jiffies; + return; + } + + if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) && + !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { + lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN; + goto add_it; + } + if (lkb->lkb_exflags & DLM_LKF_TIMEOUT) + goto add_it; + return; + + add_it: + DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb);); + mutex_lock(&ls->ls_timeout_mutex); + hold_lkb(lkb); + lkb->lkb_timestamp = jiffies; + list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout); + mutex_unlock(&ls->ls_timeout_mutex); +} + +static void del_timeout(struct dlm_lkb *lkb) +{ + struct dlm_ls *ls = lkb->lkb_resource->res_ls; + + mutex_lock(&ls->ls_timeout_mutex); + if (!list_empty(&lkb->lkb_time_list)) { + list_del_init(&lkb->lkb_time_list); + unhold_lkb(lkb); + } + mutex_unlock(&ls->ls_timeout_mutex); +} + +/* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and + lkb_lksb_timeout without lock_rsb? Note: we can't lock timeout_mutex + and then lock rsb because of lock ordering in add_timeout. We may need + to specify some special timeout-related bits in the lkb that are just to + be accessed under the timeout_mutex. */ + +void dlm_scan_timeout(struct dlm_ls *ls) +{ + struct dlm_rsb *r; + struct dlm_lkb *lkb; + int do_cancel, do_warn; + + for (;;) { + if (dlm_locking_stopped(ls)) + break; + + do_cancel = 0; + do_warn = 0; + mutex_lock(&ls->ls_timeout_mutex); + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) { + + if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) && + time_after_eq(jiffies, lkb->lkb_timestamp + + lkb->lkb_timeout_cs * HZ/100)) + do_cancel = 1; + + if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) && + time_after_eq(jiffies, lkb->lkb_timestamp + + dlm_config.ci_timewarn_cs * HZ/100)) + do_warn = 1; + + if (!do_cancel && !do_warn) + continue; + hold_lkb(lkb); + break; + } + mutex_unlock(&ls->ls_timeout_mutex); + + if (!do_cancel && !do_warn) + break; + + r = lkb->lkb_resource; + hold_rsb(r); + lock_rsb(r); + + if (do_warn) { + /* clear flag so we only warn once */ + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; + if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT)) + del_timeout(lkb); + dlm_timeout_warn(lkb); + } + + if (do_cancel) { + log_debug(ls, "timeout cancel %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); + lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN; + lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL; + del_timeout(lkb); + _cancel_lock(r, lkb); + } + + unlock_rsb(r); + unhold_rsb(r); + dlm_put_lkb(lkb); + } +} + +/* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping + dlm_recoverd before checking/setting ls_recover_begin. */ + +void dlm_adjust_timeouts(struct dlm_ls *ls) +{ + struct dlm_lkb *lkb; + long adj = jiffies - ls->ls_recover_begin; + + ls->ls_recover_begin = 0; + mutex_lock(&ls->ls_timeout_mutex); + list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) + lkb->lkb_timestamp += adj; + mutex_unlock(&ls->ls_timeout_mutex); +} + /* lkb is master or local copy */ static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) @@ -1275,10 +1414,8 @@ * queue for one resource. The granted mode of each lock blocks the requested * mode of the other lock." * - * Part 2: if the granted mode of lkb is preventing the first lkb in the - * convert queue from being granted, then demote lkb (set grmode to NL). - * This second form requires that we check for conv-deadlk even when - * now == 0 in _can_be_granted(). + * Part 2: if the granted mode of lkb is preventing an earlier lkb in the + * convert queue from being granted, then deadlk/demote lkb. * * Example: * Granted Queue: empty @@ -1287,41 +1424,52 @@ * * The first lock can't be granted because of the granted mode of the second * lock and the second lock can't be granted because it's not first in the - * list. We demote the granted mode of the second lock (the lkb passed to this - * function). + * list. We either cancel lkb's conversion (PR->EX) and return EDEADLK, or we + * demote the granted mode of lkb (from PR to NL) if it has the CONVDEADLK + * flag set and return DEMOTED in the lksb flags. + * + * Originally, this function detected conv-deadlk in a more limited scope: + * - if !modes_compat(lkb1, lkb2) && !modes_compat(lkb2, lkb1), or + * - if lkb1 was the first entry in the queue (not just earlier), and was + * blocked by the granted mode of lkb2, and there was nothing on the + * granted queue preventing lkb1 from being granted immediately, i.e. + * lkb2 was the only thing preventing lkb1 from being granted. + * + * That second condition meant we'd only say there was conv-deadlk if + * resolving it (by demotion) would lead to the first lock on the convert + * queue being granted right away. It allowed conversion deadlocks to exist + * between locks on the convert queue while they couldn't be granted anyway. * - * After the resolution, the "grant pending" function needs to go back and try - * to grant locks on the convert queue again since the first lock can now be - * granted. + * Now, we detect and take action on conversion deadlocks immediately when + * they're created, even if they may not be immediately consequential. If + * lkb1 exists anywhere in the convert queue and lkb2 comes in with a granted + * mode that would prevent lkb1's conversion from being granted, we do a + * deadlk/demote on lkb2 right away and don't let it onto the convert queue. + * I think this means that the lkb_is_ahead condition below should always + * be zero, i.e. there will never be conv-deadlk between two locks that are + * both already on the convert queue. */ -static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) +static int conversion_deadlock_detect(struct dlm_rsb *r, struct dlm_lkb *lkb2) { - struct dlm_lkb *this, *first = NULL, *self = NULL; + struct dlm_lkb *lkb1; + int lkb_is_ahead = 0; - list_for_each_entry(this, &rsb->res_convertqueue, lkb_statequeue) { - if (!first) - first = this; - if (this == lkb) { - self = lkb; + list_for_each_entry(lkb1, &r->res_convertqueue, lkb_statequeue) { + if (lkb1 == lkb2) { + lkb_is_ahead = 1; continue; } - if (!modes_compat(this, lkb) && !modes_compat(lkb, this)) - return 1; - } - - /* if lkb is on the convert queue and is preventing the first - from being granted, then there's deadlock and we demote lkb. - multiple converting locks may need to do this before the first - converting lock can be granted. */ - - if (self && self != first) { - if (!modes_compat(lkb, first) && - !queue_conflict(&rsb->res_grantqueue, first)) - return 1; + if (!lkb_is_ahead) { + if (!modes_compat(lkb2, lkb1)) + return 1; + } else { + if (!modes_compat(lkb2, lkb1) && + !modes_compat(lkb1, lkb2)) + return 1; + } } - return 0; } @@ -1450,42 +1598,57 @@ if (!now && !conv && list_empty(&r->res_convertqueue) && first_in_list(lkb, &r->res_waitqueue)) return 1; - out: - /* - * The following, enabled by CONVDEADLK, departs from VMS. - */ - - if (conv && (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) && - conversion_deadlock_detect(r, lkb)) { - lkb->lkb_grmode = DLM_LOCK_NL; - lkb->lkb_sbflags |= DLM_SBF_DEMOTED; - } - return 0; } -/* - * The ALTPR and ALTCW flags aren't traditional lock manager flags, but are a - * simple way to provide a big optimization to applications that can use them. - */ - -static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) +static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now, + int *err) { - uint32_t flags = lkb->lkb_exflags; int rv; int8_t alt = 0, rqmode = lkb->lkb_rqmode; + int8_t is_convert = (lkb->lkb_grmode != DLM_LOCK_IV); + + if (err) + *err = 0; rv = _can_be_granted(r, lkb, now); if (rv) goto out; - if (lkb->lkb_sbflags & DLM_SBF_DEMOTED) + /* + * The CONVDEADLK flag is non-standard and tells the dlm to resolve + * conversion deadlocks by demoting grmode to NL, otherwise the dlm + * cancels one of the locks. + */ + + if (is_convert && can_be_queued(lkb) && + conversion_deadlock_detect(r, lkb)) { + if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) { + lkb->lkb_grmode = DLM_LOCK_NL; + lkb->lkb_sbflags |= DLM_SBF_DEMOTED; + } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { + if (err) + *err = -EDEADLK; + else { + log_print("can_be_granted deadlock %x now %d", + lkb->lkb_id, now); + dlm_dump_rsb(r); + } + } goto out; + } - if (rqmode != DLM_LOCK_PR && flags & DLM_LKF_ALTPR) + /* + * The ALTPR and ALTCW flags are non-standard and tell the dlm to try + * to grant a request in a mode other than the normal rqmode. It's a + * simple way to provide a big optimization to applications that can + * use them. + */ + + if (rqmode != DLM_LOCK_PR && (lkb->lkb_exflags & DLM_LKF_ALTPR)) alt = DLM_LOCK_PR; - else if (rqmode != DLM_LOCK_CW && flags & DLM_LKF_ALTCW) + else if (rqmode != DLM_LOCK_CW && (lkb->lkb_exflags & DLM_LKF_ALTCW)) alt = DLM_LOCK_CW; if (alt) { @@ -1500,10 +1663,20 @@ return rv; } +/* FIXME: I don't think that can_be_granted() can/will demote or find deadlock + for locks pending on the convert list. Once verified (watch for these + log_prints), we should be able to just call _can_be_granted() and not + bother with the demote/deadlk cases here (and there's no easy way to deal + with a deadlk here, we'd have to generate something like grant_lock with + the deadlk error.) */ + +/* returns the highest requested mode of all blocked conversions */ + static int grant_pending_convert(struct dlm_rsb *r, int high) { struct dlm_lkb *lkb, *s; int hi, demoted, quit, grant_restart, demote_restart; + int deadlk; quit = 0; restart: @@ -1513,14 +1686,29 @@ list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) { demoted = is_demoted(lkb); - if (can_be_granted(r, lkb, 0)) { + deadlk = 0; + + if (can_be_granted(r, lkb, 0, &deadlk)) { grant_lock_pending(r, lkb); grant_restart = 1; - } else { - hi = max_t(int, lkb->lkb_rqmode, hi); - if (!demoted && is_demoted(lkb)) - demote_restart = 1; + continue; + } + + if (!demoted && is_demoted(lkb)) { + log_print("WARN: pending demoted %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); + demote_restart = 1; + continue; + } + + if (deadlk) { + log_print("WARN: pending deadlock %x node %d %s", + lkb->lkb_id, lkb->lkb_nodeid, r->res_name); + dlm_dump_rsb(r); + continue; } + + hi = max_t(int, lkb->lkb_rqmode, hi); } if (grant_restart) @@ -1538,7 +1726,7 @@ struct dlm_lkb *lkb, *s; list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { - if (can_be_granted(r, lkb, 0)) + if (can_be_granted(r, lkb, 0, NULL)) grant_lock_pending(r, lkb); else high = max_t(int, lkb->lkb_rqmode, high); @@ -1733,7 +1921,7 @@ } static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, - int namelen, uint32_t parent_lkid, void *ast, + int namelen, unsigned long timeout_cs, void *ast, void *astarg, void *bast, struct dlm_args *args) { int rv = -EINVAL; @@ -1776,10 +1964,6 @@ if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr) goto out; - /* parent/child locks not yet supported */ - if (parent_lkid) - goto out; - if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid) goto out; @@ -1791,6 +1975,7 @@ args->astaddr = ast; args->astparam = (long) astarg; args->bastaddr = bast; + args->timeout = timeout_cs; args->mode = mode; args->lksb = lksb; rv = 0; @@ -1845,6 +2030,7 @@ lkb->lkb_lksb = args->lksb; lkb->lkb_lvbptr = args->lksb->sb_lvbptr; lkb->lkb_ownpid = (int) current->pid; + lkb->lkb_timeout_cs = args->timeout; rv = 0; out: return rv; @@ -1903,6 +2089,9 @@ if (is_overlap(lkb)) goto out; + /* don't let scand try to do a cancel */ + del_timeout(lkb); + if (lkb->lkb_flags & DLM_IFL_RESEND) { lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL; rv = -EBUSY; @@ -1934,6 +2123,9 @@ if (is_overlap_unlock(lkb)) goto out; + /* don't let scand try to do a cancel */ + del_timeout(lkb); + if (lkb->lkb_flags & DLM_IFL_RESEND) { lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK; rv = -EBUSY; @@ -1984,7 +2176,7 @@ { int error = 0; - if (can_be_granted(r, lkb, 1)) { + if (can_be_granted(r, lkb, 1, NULL)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); goto out; @@ -1994,6 +2186,7 @@ error = -EINPROGRESS; add_lkb(r, lkb, DLM_LKSTS_WAITING); send_blocking_asts(r, lkb); + add_timeout(lkb); goto out; } @@ -2009,16 +2202,32 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) { int error = 0; + int deadlk = 0; /* changing an existing lock may allow others to be granted */ - if (can_be_granted(r, lkb, 1)) { + if (can_be_granted(r, lkb, 1, &deadlk)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); grant_pending_locks(r); goto out; } + /* can_be_granted() detected that this lock would block in a conversion + deadlock, so we leave it on the granted queue and return EDEADLK in + the ast for the convert. */ + + if (deadlk) { + /* it's left on the granted queue */ + log_debug(r->res_ls, "deadlock %x node %d sts%d g%d r%d %s", + lkb->lkb_id, lkb->lkb_nodeid, lkb->lkb_status, + lkb->lkb_grmode, lkb->lkb_rqmode, r->res_name); + revert_lock(r, lkb); + queue_cast(r, lkb, -EDEADLK); + error = -EDEADLK; + goto out; + } + /* is_demoted() means the can_be_granted() above set the grmode to NL, and left us on the granted queue. This auto-demotion (due to CONVDEADLK) might mean other locks, and/or this lock, are @@ -2041,6 +2250,7 @@ del_lkb(r, lkb); add_lkb(r, lkb, DLM_LKSTS_CONVERT); send_blocking_asts(r, lkb); + add_timeout(lkb); goto out; } @@ -2274,7 +2484,7 @@ if (!ls) return -EINVAL; - lock_recovery(ls); + dlm_lock_recovery(ls); if (convert) error = find_lkb(ls, lksb->sb_lkid, &lkb); @@ -2284,7 +2494,7 @@ if (error) goto out; - error = set_lock_args(mode, lksb, flags, namelen, parent_lkid, ast, + error = set_lock_args(mode, lksb, flags, namelen, 0, ast, astarg, bast, &args); if (error) goto out_put; @@ -2299,10 +2509,10 @@ out_put: if (convert || error) __put_lkb(ls, lkb); - if (error == -EAGAIN) + if (error == -EAGAIN || error == -EDEADLK) error = 0; out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); dlm_put_lockspace(ls); return error; } @@ -2322,7 +2532,7 @@ if (!ls) return -EINVAL; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -2344,7 +2554,7 @@ out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); dlm_put_lockspace(ls); return error; } @@ -2384,7 +2594,7 @@ pass into lowcomms_commit and a message buffer (mb) that we write our data into */ - mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) return -ENOBUFS; @@ -3111,9 +3321,10 @@ lkb->lkb_remid = ms->m_lkid; if (is_altmode(lkb)) munge_altmode(lkb, ms); - if (result) + if (result) { add_lkb(r, lkb, DLM_LKSTS_WAITING); - else { + add_timeout(lkb); + } else { grant_lock_pc(r, lkb, ms); queue_cast(r, lkb, 0); } @@ -3172,6 +3383,12 @@ queue_cast(r, lkb, -EAGAIN); break; + case -EDEADLK: + receive_flags_reply(lkb, ms); + revert_lock_pc(r, lkb); + queue_cast(r, lkb, -EDEADLK); + break; + case -EINPROGRESS: /* convert was queued on remote master */ receive_flags_reply(lkb, ms); @@ -3179,6 +3396,7 @@ munge_demoted(lkb, ms); del_lkb(r, lkb); add_lkb(r, lkb, DLM_LKSTS_CONVERT); + add_timeout(lkb); break; case 0: @@ -3298,8 +3516,7 @@ case -DLM_ECANCEL: receive_flags_reply(lkb, ms); revert_lock_pc(r, lkb); - if (ms->m_result) - queue_cast(r, lkb, -DLM_ECANCEL); + queue_cast(r, lkb, -DLM_ECANCEL); break; case 0: break; @@ -3424,7 +3641,7 @@ } } - if (lock_recovery_try(ls)) + if (dlm_lock_recovery_try(ls)) break; schedule(); } @@ -3503,7 +3720,7 @@ log_error(ls, "unknown message type %d", ms->m_type); } - unlock_recovery(ls); + dlm_unlock_recovery(ls); out: dlm_put_lockspace(ls); dlm_astd_wake(); @@ -4034,13 +4251,13 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, uint32_t flags, void *name, unsigned int namelen, - uint32_t parent_lkid) + unsigned long timeout_cs) { struct dlm_lkb *lkb; struct dlm_args args; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = create_lkb(ls, &lkb); if (error) { @@ -4062,7 +4279,7 @@ When DLM_IFL_USER is set, the dlm knows that this is a userspace lock and that lkb_astparam is the dlm_user_args structure. */ - error = set_lock_args(mode, &ua->lksb, flags, namelen, parent_lkid, + error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); lkb->lkb_flags |= DLM_IFL_USER; ua->old_mode = DLM_LOCK_IV; @@ -4094,19 +4311,20 @@ list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); spin_unlock(&ua->proc->locks_spin); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); return error; } int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, - int mode, uint32_t flags, uint32_t lkid, char *lvb_in) + int mode, uint32_t flags, uint32_t lkid, char *lvb_in, + unsigned long timeout_cs) { struct dlm_lkb *lkb; struct dlm_args args; struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4127,6 +4345,7 @@ if (lvb_in && ua->lksb.sb_lvbptr) memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); + ua->xid = ua_tmp->xid; ua->castparam = ua_tmp->castparam; ua->castaddr = ua_tmp->castaddr; ua->bastparam = ua_tmp->bastparam; @@ -4134,19 +4353,19 @@ ua->user_lksb = ua_tmp->user_lksb; ua->old_mode = lkb->lkb_grmode; - error = set_lock_args(mode, &ua->lksb, flags, 0, 0, DLM_FAKE_USER_AST, - ua, DLM_FAKE_USER_AST, &args); + error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs, + DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); if (error) goto out_put; error = convert_lock(ls, lkb, &args); - if (error == -EINPROGRESS || error == -EAGAIN) + if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK) error = 0; out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } @@ -4159,7 +4378,7 @@ struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4194,7 +4413,7 @@ out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } @@ -4207,7 +4426,7 @@ struct dlm_user_args *ua; int error; - lock_recovery(ls); + dlm_lock_recovery(ls); error = find_lkb(ls, lkid, &lkb); if (error) @@ -4231,11 +4450,59 @@ out_put: dlm_put_lkb(lkb); out: - unlock_recovery(ls); + dlm_unlock_recovery(ls); kfree(ua_tmp); return error; } +int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid) +{ + struct dlm_lkb *lkb; + struct dlm_args args; + struct dlm_user_args *ua; + struct dlm_rsb *r; + int error; + + dlm_lock_recovery(ls); + + error = find_lkb(ls, lkid, &lkb); + if (error) + goto out; + + ua = (struct dlm_user_args *)lkb->lkb_astparam; + + error = set_unlock_args(flags, ua, &args); + if (error) + goto out_put; + + /* same as cancel_lock(), but set DEADLOCK_CANCEL after lock_rsb */ + + r = lkb->lkb_resource; + hold_rsb(r); + lock_rsb(r); + + error = validate_unlock_args(lkb, &args); + if (error) + goto out_r; + lkb->lkb_flags |= DLM_IFL_DEADLOCK_CANCEL; + + error = _cancel_lock(r, lkb); + out_r: + unlock_rsb(r); + put_rsb(r); + + if (error == -DLM_ECANCEL) + error = 0; + /* from validate_unlock_args() */ + if (error == -EBUSY) + error = 0; + out_put: + dlm_put_lkb(lkb); + out: + dlm_unlock_recovery(ls); + return error; +} + /* lkb's that are removed from the waiters list by revert are just left on the orphans list with the granted orphan locks, to be freed by purge */ @@ -4314,12 +4581,13 @@ { struct dlm_lkb *lkb, *safe; - lock_recovery(ls); + dlm_lock_recovery(ls); while (1) { lkb = del_proc_lock(ls, proc); if (!lkb) break; + del_timeout(lkb); if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) orphan_proc_lock(ls, lkb); else @@ -4347,7 +4615,7 @@ } mutex_unlock(&ls->ls_clear_proc_locks); - unlock_recovery(ls); + dlm_unlock_recovery(ls); } static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) @@ -4429,12 +4697,12 @@ if (nodeid != dlm_our_nodeid()) { error = send_purge(ls, nodeid, pid); } else { - lock_recovery(ls); + dlm_lock_recovery(ls); if (pid == current->pid) purge_proc_locks(ls, proc); else do_purge(ls, nodeid, pid); - unlock_recovery(ls); + dlm_unlock_recovery(ls); } return error; } --- linux-source-2.6.22-2.6.22.orig/fs/dlm/netlink.c +++ linux-source-2.6.22-2.6.22/fs/dlm/netlink.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + */ + +#include +#include +#include + +#include "dlm_internal.h" + +static uint32_t dlm_nl_seqnum; +static uint32_t listener_nlpid; + +static struct genl_family family = { + .id = GENL_ID_GENERATE, + .name = DLM_GENL_NAME, + .version = DLM_GENL_VERSION, +}; + +static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size) +{ + struct sk_buff *skb; + void *data; + + skb = genlmsg_new(size, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + /* add the message headers */ + data = genlmsg_put(skb, 0, dlm_nl_seqnum++, &family, 0, cmd); + if (!data) { + nlmsg_free(skb); + return -EINVAL; + } + + *skbp = skb; + return 0; +} + +static struct dlm_lock_data *mk_data(struct sk_buff *skb) +{ + struct nlattr *ret; + + ret = nla_reserve(skb, DLM_TYPE_LOCK, sizeof(struct dlm_lock_data)); + if (!ret) + return NULL; + return nla_data(ret); +} + +static int send_data(struct sk_buff *skb) +{ + struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); + void *data = genlmsg_data(genlhdr); + int rv; + + rv = genlmsg_end(skb, data); + if (rv < 0) { + nlmsg_free(skb); + return rv; + } + + return genlmsg_unicast(skb, listener_nlpid); +} + +static int user_cmd(struct sk_buff *skb, struct genl_info *info) +{ + listener_nlpid = info->snd_pid; + printk("user_cmd nlpid %u\n", listener_nlpid); + return 0; +} + +static struct genl_ops dlm_nl_ops = { + .cmd = DLM_CMD_HELLO, + .doit = user_cmd, +}; + +int dlm_netlink_init(void) +{ + int rv; + + rv = genl_register_family(&family); + if (rv) + return rv; + + rv = genl_register_ops(&family, &dlm_nl_ops); + if (rv < 0) + goto err; + return 0; + err: + genl_unregister_family(&family); + return rv; +} + +void dlm_netlink_exit(void) +{ + genl_unregister_ops(&family, &dlm_nl_ops); + genl_unregister_family(&family); +} + +static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) +{ + struct dlm_rsb *r = lkb->lkb_resource; + struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam; + + memset(data, 0, sizeof(struct dlm_lock_data)); + + data->version = DLM_LOCK_DATA_VERSION; + data->nodeid = lkb->lkb_nodeid; + data->ownpid = lkb->lkb_ownpid; + data->id = lkb->lkb_id; + data->remid = lkb->lkb_remid; + data->status = lkb->lkb_status; + data->grmode = lkb->lkb_grmode; + data->rqmode = lkb->lkb_rqmode; + data->timestamp = lkb->lkb_timestamp; + if (ua) + data->xid = ua->xid; + if (r) { + data->lockspace_id = r->res_ls->ls_global_id; + data->resource_namelen = r->res_length; + memcpy(data->resource_name, r->res_name, r->res_length); + } +} + +void dlm_timeout_warn(struct dlm_lkb *lkb) +{ + struct dlm_lock_data *data; + struct sk_buff *send_skb; + size_t size; + int rv; + + size = nla_total_size(sizeof(struct dlm_lock_data)) + + nla_total_size(0); /* why this? */ + + rv = prepare_data(DLM_CMD_TIMEOUT, &send_skb, size); + if (rv < 0) + return; + + data = mk_data(send_skb); + if (!data) { + nlmsg_free(send_skb); + return; + } + + fill_data(data, lkb); + + send_data(send_skb); +} + --- linux-source-2.6.22-2.6.22.orig/fs/dlm/main.c +++ linux-source-2.6.22-2.6.22/fs/dlm/main.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -25,6 +25,8 @@ static inline int dlm_register_debugfs(void) { return 0; } static inline void dlm_unregister_debugfs(void) { } #endif +int dlm_netlink_init(void); +void dlm_netlink_exit(void); static int __init init_dlm(void) { @@ -50,10 +52,16 @@ if (error) goto out_debug; + error = dlm_netlink_init(); + if (error) + goto out_user; + printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); return 0; + out_user: + dlm_user_exit(); out_debug: dlm_unregister_debugfs(); out_config: @@ -68,6 +76,7 @@ static void __exit exit_dlm(void) { + dlm_netlink_exit(); dlm_user_exit(); dlm_config_exit(); dlm_memory_exit(); --- linux-source-2.6.22-2.6.22.orig/fs/dlm/config.h +++ linux-source-2.6.22-2.6.22/fs/dlm/config.h @@ -27,6 +27,7 @@ int ci_scan_secs; int ci_log_debug; int ci_protocol; + int ci_timewarn_cs; }; extern struct dlm_config_info dlm_config; --- linux-source-2.6.22-2.6.22.orig/fs/dlm/user.c +++ linux-source-2.6.22-2.6.22/fs/dlm/user.c @@ -33,16 +33,17 @@ struct dlm_lock_params32 { __u8 mode; __u8 namelen; - __u16 flags; + __u16 unused; + __u32 flags; __u32 lkid; __u32 parent; - + __u64 xid; + __u64 timeout; __u32 castparam; __u32 castaddr; __u32 bastparam; __u32 bastaddr; __u32 lksb; - char lvb[DLM_USER_LVB_LEN]; char name[0]; }; @@ -68,6 +69,7 @@ }; struct dlm_lock_result32 { + __u32 version[3]; __u32 length; __u32 user_astaddr; __u32 user_astparam; @@ -102,6 +104,8 @@ kb->i.lock.flags = kb32->i.lock.flags; kb->i.lock.lkid = kb32->i.lock.lkid; kb->i.lock.parent = kb32->i.lock.parent; + kb->i.lock.xid = kb32->i.lock.xid; + kb->i.lock.timeout = kb32->i.lock.timeout; kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam; kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr; kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam; @@ -115,6 +119,10 @@ static void compat_output(struct dlm_lock_result *res, struct dlm_lock_result32 *res32) { + res32->version[0] = res->version[0]; + res32->version[1] = res->version[1]; + res32->version[2] = res->version[2]; + res32->user_astaddr = (__u32)(long)res->user_astaddr; res32->user_astparam = (__u32)(long)res->user_astparam; res32->user_lksb = (__u32)(long)res->user_lksb; @@ -130,6 +138,36 @@ } #endif +/* Figure out if this lock is at the end of its life and no longer + available for the application to use. The lkb still exists until + the final ast is read. A lock becomes EOL in three situations: + 1. a noqueue request fails with EAGAIN + 2. an unlock completes with EUNLOCK + 3. a cancel of a waiting request completes with ECANCEL/EDEADLK + An EOL lock needs to be removed from the process's list of locks. + And we can't allow any new operation on an EOL lock. This is + not related to the lifetime of the lkb struct which is managed + entirely by refcount. */ + +static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) +{ + switch (sb_status) { + case -DLM_EUNLOCK: + return 1; + case -DLM_ECANCEL: + case -ETIMEDOUT: + case -EDEADLK: + if (lkb->lkb_grmode == DLM_LOCK_IV) + return 1; + break; + case -EAGAIN: + if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV) + return 1; + break; + } + return 0; +} + /* we could possibly check if the cancel of an orphan has resulted in the lkb being removed and then remove that lkb from the orphans list and free it */ @@ -176,25 +214,7 @@ log_debug(ls, "ast overlap %x status %x %x", lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags); - /* Figure out if this lock is at the end of its life and no longer - available for the application to use. The lkb still exists until - the final ast is read. A lock becomes EOL in three situations: - 1. a noqueue request fails with EAGAIN - 2. an unlock completes with EUNLOCK - 3. a cancel of a waiting request completes with ECANCEL - An EOL lock needs to be removed from the process's list of locks. - And we can't allow any new operation on an EOL lock. This is - not related to the lifetime of the lkb struct which is managed - entirely by refcount. */ - - if (type == AST_COMP && - lkb->lkb_grmode == DLM_LOCK_IV && - ua->lksb.sb_status == -EAGAIN) - eol = 1; - else if (ua->lksb.sb_status == -DLM_EUNLOCK || - (ua->lksb.sb_status == -DLM_ECANCEL && - lkb->lkb_grmode == DLM_LOCK_IV)) - eol = 1; + eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type); if (eol) { lkb->lkb_ast_type &= ~AST_BAST; lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; @@ -252,16 +272,18 @@ ua->castaddr = params->castaddr; ua->bastparam = params->bastparam; ua->bastaddr = params->bastaddr; + ua->xid = params->xid; if (params->flags & DLM_LKF_CONVERT) error = dlm_user_convert(ls, ua, params->mode, params->flags, - params->lkid, params->lvb); + params->lkid, params->lvb, + (unsigned long) params->timeout); else { error = dlm_user_request(ls, ua, params->mode, params->flags, params->name, params->namelen, - params->parent); + (unsigned long) params->timeout); if (!error) error = ua->lksb.sb_lkid; } @@ -299,6 +321,22 @@ return error; } +static int device_user_deadlock(struct dlm_user_proc *proc, + struct dlm_lock_params *params) +{ + struct dlm_ls *ls; + int error; + + ls = dlm_find_lockspace_local(proc->lockspace); + if (!ls) + return -ENOENT; + + error = dlm_user_deadlock(ls, params->flags, params->lkid); + + dlm_put_lockspace(ls); + return error; +} + static int create_misc_device(struct dlm_ls *ls, char *name) { int error, len; @@ -348,7 +386,7 @@ return -EPERM; error = dlm_new_lockspace(params->name, strlen(params->name), - &lockspace, 0, DLM_USER_LVB_LEN); + &lockspace, params->flags, DLM_USER_LVB_LEN); if (error) return error; @@ -524,6 +562,14 @@ error = device_user_unlock(proc, &kbuf->i.lock); break; + case DLM_USER_DEADLOCK: + if (!proc) { + log_print("no locking on control device"); + goto out_sig; + } + error = device_user_deadlock(proc, &kbuf->i.lock); + break; + case DLM_USER_CREATE_LOCKSPACE: if (proc) { log_print("create/remove only on control device"); @@ -641,6 +687,9 @@ int struct_len; memset(&result, 0, sizeof(struct dlm_lock_result)); + result.version[0] = DLM_DEVICE_VERSION_MAJOR; + result.version[1] = DLM_DEVICE_VERSION_MINOR; + result.version[2] = DLM_DEVICE_VERSION_PATCH; memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb)); result.user_lksb = ua->user_lksb; @@ -699,6 +748,20 @@ return error; } +static int copy_version_to_user(char __user *buf, size_t count) +{ + struct dlm_device_version ver; + + memset(&ver, 0, sizeof(struct dlm_device_version)); + ver.version[0] = DLM_DEVICE_VERSION_MAJOR; + ver.version[1] = DLM_DEVICE_VERSION_MINOR; + ver.version[2] = DLM_DEVICE_VERSION_PATCH; + + if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version))) + return -EFAULT; + return sizeof(struct dlm_device_version); +} + /* a read returns a single ast described in a struct dlm_lock_result */ static ssize_t device_read(struct file *file, char __user *buf, size_t count, @@ -710,6 +773,16 @@ DECLARE_WAITQUEUE(wait, current); int error, type=0, bmode=0, removed = 0; + if (count == sizeof(struct dlm_device_version)) { + error = copy_version_to_user(buf, count); + return error; + } + + if (!proc) { + log_print("non-version read from control device %zu", count); + return -EINVAL; + } + #ifdef CONFIG_COMPAT if (count < sizeof(struct dlm_lock_result32)) #else @@ -747,11 +820,6 @@ } } - if (list_empty(&proc->asts)) { - spin_unlock(&proc->asts_spin); - return -EAGAIN; - } - /* there may be both completion and blocking asts to return for the lkb, don't remove lkb from asts list unless no asts remain */ @@ -823,6 +891,7 @@ static const struct file_operations ctl_device_fops = { .open = ctl_device_open, .release = ctl_device_close, + .read = device_read, .write = device_write, .owner = THIS_MODULE, }; --- linux-source-2.6.22-2.6.22.orig/fs/dlm/member.c +++ linux-source-2.6.22-2.6.22/fs/dlm/member.c @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -233,6 +233,12 @@ *neg_out = neg; error = ping_members(ls); + if (!error || error == -EPROTO) { + /* new_lockspace() may be waiting to know if the config + is good or bad */ + ls->ls_members_result = error; + complete(&ls->ls_members_done); + } if (error) goto out; @@ -284,6 +290,9 @@ dlm_recoverd_suspend(ls); ls->ls_recover_status = 0; dlm_recoverd_resume(ls); + + if (!ls->ls_recover_begin) + ls->ls_recover_begin = jiffies; return 0; } --- linux-source-2.6.22-2.6.22.orig/fs/dlm/rcom.c +++ linux-source-2.6.22-2.6.22/fs/dlm/rcom.c @@ -38,7 +38,7 @@ char *mb; int mb_len = sizeof(struct dlm_rcom) + len; - mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) { log_print("create_rcom to %d type %d len %d ENOBUFS", to_nodeid, type, len); @@ -90,7 +90,7 @@ log_error(ls, "version mismatch: %x nodeid %d: %x", DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid, rc->rc_header.h_version); - return -EINVAL; + return -EPROTO; } if (rf->rf_lvblen != ls->ls_lvblen || @@ -98,7 +98,7 @@ log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", ls->ls_lvblen, ls->ls_exflags, nodeid, rf->rf_lvblen, rf->rf_lsflags); - return -EINVAL; + return -EPROTO; } return 0; } @@ -386,7 +386,8 @@ dlm_recover_process_copy(ls, rc_in); } -static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) +static int send_ls_not_ready(struct dlm_ls *ls, int nodeid, + struct dlm_rcom *rc_in) { struct dlm_rcom *rc; struct rcom_config *rf; @@ -394,7 +395,7 @@ char *mb; int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); - mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); + mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb); if (!mh) return -ENOBUFS; memset(mb, 0, mb_len); @@ -464,7 +465,7 @@ log_print("lockspace %x from %d type %x not found", hd->h_lockspace, nodeid, rc->rc_type); if (rc->rc_type == DLM_RCOM_STATUS) - send_ls_not_ready(nodeid, rc); + send_ls_not_ready(ls, nodeid, rc); return; } --- linux-source-2.6.22-2.6.22.orig/fs/dlm/lowcomms.c +++ linux-source-2.6.22-2.6.22/fs/dlm/lowcomms.c @@ -260,7 +260,7 @@ static void lowcomms_data_ready(struct sock *sk, int count_unused) { struct connection *con = sock2con(sk); - if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) + if (con && !test_and_set_bit(CF_READ_PENDING, &con->flags)) queue_work(recv_workqueue, &con->rwork); } @@ -268,7 +268,7 @@ { struct connection *con = sock2con(sk); - if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) + if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) queue_work(send_workqueue, &con->swork); } @@ -313,6 +313,7 @@ in6_addr->sin6_port = cpu_to_be16(port); *addr_len = sizeof(struct sockaddr_in6); } + memset((char *)saddr + *addr_len, 0, sizeof(struct sockaddr_storage) - *addr_len); } /* Close a remote connection and tidy up */ @@ -332,6 +333,7 @@ __free_page(con->rx_page); con->rx_page = NULL; } + con->retries = 0; mutex_unlock(&con->sock_mutex); } @@ -631,7 +633,7 @@ out_close: mutex_unlock(&con->sock_mutex); - if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { + if (ret != -EAGAIN) { close_connection(con, false); /* Reconnect when there is something to send */ } @@ -719,12 +721,20 @@ INIT_WORK(&othercon->swork, process_send_sockets); INIT_WORK(&othercon->rwork, process_recv_sockets); set_bit(CF_IS_OTHERCON, &othercon->flags); + } + if (!othercon->sock) { newcon->othercon = othercon; + othercon->sock = newsock; + newsock->sk->sk_user_data = othercon; + add_sock(newsock, othercon); + addcon = othercon; + } + else { + printk("Extra connection from node %d attempted\n", nodeid); + result = -EAGAIN; + mutex_unlock(&newcon->sock_mutex); + goto accept_err; } - othercon->sock = newsock; - newsock->sk->sk_user_data = othercon; - add_sock(newsock, othercon); - addcon = othercon; } else { newsock->sk->sk_user_data = newcon; @@ -854,7 +864,7 @@ static void tcp_connect_to_sock(struct connection *con) { int result = -EHOSTUNREACH; - struct sockaddr_storage saddr; + struct sockaddr_storage saddr, src_addr; int addr_len; struct socket *sock; @@ -888,6 +898,17 @@ con->connect_action = tcp_connect_to_sock; add_sock(sock, con); + /* Bind to our cluster-known address connecting to avoid + routing problems */ + memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr)); + make_sockaddr(&src_addr, 0, &addr_len); + result = sock->ops->bind(sock, (struct sockaddr *) &src_addr, + addr_len); + if (result < 0) { + printk("dlm: could not bind for connect: %d\n", result); + /* This *may* not indicate a critical error */ + } + make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); log_print("connecting to %d", con->nodeid); @@ -1116,8 +1137,6 @@ log_print("Using TCP for communications"); - set_bit(CF_IS_OTHERCON, &con->flags); - sock = tcp_create_listen_sock(con, dlm_local_addr[0]); if (sock) { add_sock(sock, con); @@ -1256,14 +1275,15 @@ if (len) { ret = sendpage(con->sock, e->page, offset, len, msg_flags); - if (ret == -EAGAIN || ret == 0) + if (ret == -EAGAIN || ret == 0) { + cond_resched(); goto out; + } if (ret <= 0) goto send_error; - } else { + } /* Don't starve people filling buffers */ cond_resched(); - } spin_lock(&con->writequeue_lock); e->offset += ret; @@ -1400,8 +1420,11 @@ down(&connections_lock); for (i = 0; i <= max_nodeid; i++) { con = __nodeid2con(i, 0); - if (con) - con->flags |= 0xFF; + if (con) { + con->flags |= 0x0F; + if (con->sock) + con->sock->sk->sk_user_data = NULL; + } } up(&connections_lock); --- linux-source-2.6.22-2.6.22.orig/fs/open.c +++ linux-source-2.6.22-2.6.22/fs/open.c @@ -193,8 +193,8 @@ return error; } -int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - struct file *filp) +int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length, + unsigned int time_attrs, struct file *filp) { int err; struct iattr newattrs; @@ -214,7 +214,7 @@ newattrs.ia_valid |= should_remove_suid(dentry); mutex_lock(&dentry->d_inode->i_mutex); - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, mnt, &newattrs); mutex_unlock(&dentry->d_inode->i_mutex); return err; } @@ -269,7 +269,7 @@ error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(nd.dentry, length, 0, NULL); + error = do_truncate(nd.dentry, nd.mnt, length, 0, NULL); } put_write_access(inode); @@ -321,7 +321,8 @@ error = locks_verify_truncate(inode, file, length); if (!error) - error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); + error = do_truncate(dentry, file->f_path.mnt, length, + ATTR_MTIME|ATTR_CTIME, file); out_putf: fput(file); out: @@ -439,10 +440,8 @@ asmlinkage long sys_fchdir(unsigned int fd) { + struct nameidata nd; struct file *file; - struct dentry *dentry; - struct inode *inode; - struct vfsmount *mnt; int error; error = -EBADF; @@ -450,17 +449,17 @@ if (!file) goto out; - dentry = file->f_path.dentry; - mnt = file->f_path.mnt; - inode = dentry->d_inode; + nd.dentry = file->f_path.dentry; + nd.mnt = file->f_path.mnt; + nd.flags = 0; error = -ENOTDIR; - if (!S_ISDIR(inode->i_mode)) + if (!S_ISDIR(nd.dentry->d_inode->i_mode)) goto out_putf; - error = file_permission(file, MAY_EXEC); + error = vfs_permission(&nd, MAY_EXEC); if (!error) - set_fs_pwd(current->fs, mnt, dentry); + set_fs_pwd(current->fs, nd.mnt, nd.dentry); out_putf: fput(file); out: @@ -521,7 +520,9 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + newattrs.ia_valid |= ATTR_FILE; + newattrs.ia_file = file; + err = notify_change(dentry, file->f_path.mnt, &newattrs); mutex_unlock(&inode->i_mutex); out_putf: @@ -556,7 +557,7 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(nd.dentry, &newattrs); + error = notify_change(nd.dentry, nd.mnt, &newattrs); mutex_unlock(&inode->i_mutex); dput_and_out: @@ -570,7 +571,8 @@ return sys_fchmodat(AT_FDCWD, filename, mode); } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct dentry * dentry, struct vfsmount *mnt, + uid_t user, gid_t group, struct file *file) { struct inode * inode; int error; @@ -598,8 +600,12 @@ } if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; + if (file) { + newattrs.ia_file = file; + newattrs.ia_valid |= ATTR_FILE; + } mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = notify_change(dentry, mnt, &newattrs); mutex_unlock(&inode->i_mutex); out: return error; @@ -613,7 +619,7 @@ error = user_path_walk(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -633,7 +639,7 @@ error = __user_walk_fd(dfd, filename, follow, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -647,7 +653,7 @@ error = user_path_walk_link(filename, &nd); if (error) goto out; - error = chown_common(nd.dentry, user, group); + error = chown_common(nd.dentry, nd.mnt, user, group, NULL); path_release(&nd); out: return error; @@ -666,7 +672,7 @@ dentry = file->f_path.dentry; audit_inode(NULL, dentry->d_inode); - error = chown_common(dentry, user, group); + error = chown_common(dentry, file->f_path.mnt, user, group, file); fput(file); out: return error; --- linux-source-2.6.22-2.6.22.orig/fs/stack.c +++ linux-source-2.6.22-2.6.22/fs/stack.c @@ -1,8 +1,20 @@ +/* + * Copyright (c) 2006-2007 Erez Zadok + * Copyright (c) 2006-2007 Josef 'Jeff' Sipek + * Copyright (c) 2006-2007 Stony Brook University + * Copyright (c) 2006-2007 The Research Foundation of SUNY + * + * 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 #include #include -/* does _NOT_ require i_mutex to be held. +/* + * does _NOT_ require i_mutex to be held. * * This function cannot be inlined since i_size_{read,write} is rather * heavy-weight on 32-bit systems @@ -14,11 +26,11 @@ } EXPORT_SYMBOL_GPL(fsstack_copy_inode_size); -/* copy all attributes; get_nlinks is optional way to override the i_nlink +/* + * copy all attributes; get_nlinks is optional way to override the i_nlink * copying */ -void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, - int (*get_nlinks)(struct inode *)) +void fsstack_copy_attr_all(struct inode *dest, const struct inode *src) { dest->i_mode = src->i_mode; dest->i_uid = src->i_uid; @@ -29,14 +41,6 @@ dest->i_ctime = src->i_ctime; dest->i_blkbits = src->i_blkbits; dest->i_flags = src->i_flags; - - /* - * Update the nlinks AFTER updating the above fields, because the - * get_links callback may depend on them. - */ - if (!get_nlinks) - dest->i_nlink = src->i_nlink; - else - dest->i_nlink = (*get_nlinks)(dest); + dest->i_nlink = src->i_nlink; } EXPORT_SYMBOL_GPL(fsstack_copy_attr_all); --- linux-source-2.6.22-2.6.22.orig/kernel/sys.c +++ linux-source-2.6.22-2.6.22/kernel/sys.c @@ -1428,7 +1428,6 @@ * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. * LBT 04.03.94 */ - asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) { struct task_struct *p; @@ -1456,7 +1455,7 @@ if (!thread_group_leader(p)) goto out; - if (p->real_parent == group_leader) { + if (p->real_parent->tgid == group_leader->tgid) { err = -EPERM; if (task_session(p) != task_session(group_leader)) goto out; --- linux-source-2.6.22-2.6.22.orig/kernel/signal.c +++ linux-source-2.6.22-2.6.22/kernel/signal.c @@ -368,7 +368,7 @@ /* We only dequeue private signals from ourselves, we don't let * signalfd steal them */ - if (tsk == current) + if (likely(tsk == current)) signr = __dequeue_signal(&tsk->pending, mask, info); if (!signr) { signr = __dequeue_signal(&tsk->signal->shared_pending, @@ -415,7 +415,7 @@ if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; } - if ( signr && + if (signr && likely(tsk == current) && ((info->si_code & __SI_MASK) == __SI_TIMER) && info->si_sys_private){ /* @@ -1259,20 +1259,19 @@ void sigqueue_free(struct sigqueue *q) { unsigned long flags; + spinlock_t *lock = ¤t->sighand->siglock; + BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); /* * If the signal is still pending remove it from the - * pending queue. + * pending queue. We must hold ->siglock while testing + * q->list to serialize with collect_signal(). */ - if (unlikely(!list_empty(&q->list))) { - spinlock_t *lock = ¤t->sighand->siglock; - read_lock(&tasklist_lock); - spin_lock_irqsave(lock, flags); - if (!list_empty(&q->list)) - list_del_init(&q->list); - spin_unlock_irqrestore(lock, flags); - read_unlock(&tasklist_lock); - } + spin_lock_irqsave(lock, flags); + if (!list_empty(&q->list)) + list_del_init(&q->list); + spin_unlock_irqrestore(lock, flags); + q->flags &= ~SIGQUEUE_PREALLOC; __sigqueue_free(q); } --- linux-source-2.6.22-2.6.22.orig/kernel/relay.c +++ linux-source-2.6.22-2.6.22/kernel/relay.c @@ -91,6 +91,7 @@ return -EINVAL; vma->vm_ops = &relay_file_mmap_ops; + vma->vm_flags |= VM_DONTEXPAND; vma->vm_private_data = buf; buf->chan->cb->buf_mapped(buf, filp); --- linux-source-2.6.22-2.6.22.orig/kernel/exit.c +++ linux-source-2.6.22-2.6.22/kernel/exit.c @@ -1336,8 +1336,7 @@ int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED; exit_code = p->exit_code; - if (unlikely(!exit_code) || - unlikely(p->state & TASK_TRACED)) + if (unlikely(!exit_code) || unlikely(p->exit_state)) goto bail_ref; return wait_noreap_copyout(p, pid, uid, why, (exit_code << 8) | 0x7f, --- linux-source-2.6.22-2.6.22.orig/kernel/power/console.c +++ linux-source-2.6.22-2.6.22/kernel/power/console.c @@ -16,6 +16,7 @@ int pm_prepare_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); orig_fgconsole = fg_console; @@ -44,15 +45,18 @@ } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; +#endif return 0; } void pm_restore_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); set_console(orig_fgconsole); release_console_sem(); kmsg_redirect = orig_kmsg; +#endif return; } #endif --- linux-source-2.6.22-2.6.22.orig/kernel/power/Kconfig +++ linux-source-2.6.22-2.6.22/kernel/power/Kconfig @@ -33,13 +33,20 @@ bool "Power Management Debug Support" depends on PM ---help--- - This option enables verbose debugging support in the Power Management - code. This is helpful when debugging and reporting various PM bugs, - like suspend support. + This option enables various debugging support in the Power Management + code. This is helpful when debugging and reporting PM bugs, like + suspend support. + +config PM_VERBOSE + bool "Verbose Power Management debugging" + depends on PM_DEBUG + default n + ---help--- + This option enables verbose messages from the Power Management code. config DISABLE_CONSOLE_SUSPEND bool "Keep console(s) enabled during suspend/resume (DANGEROUS)" - depends on PM && PM_DEBUG + depends on PM_DEBUG default n ---help--- This option turns off the console suspend mechanism that prevents @@ -50,7 +57,7 @@ config PM_TRACE bool "Suspend/resume event tracing" - depends on PM && PM_DEBUG && X86_32 && EXPERIMENTAL + depends on PM_DEBUG && X86_32 && EXPERIMENTAL default n ---help--- This enables some cheesy code to save the last PM event point in the @@ -77,6 +84,21 @@ handle the wide variability of device power states; any replacements are likely to be bus or driver specific. +config PM_DISABLE_CONSOLE + bool "Disable Power Management messing with the active console" + depends on PM + default n + ---help--- + By defauly, PM will take over the active console (generally, this means + switching to the console when suspending from X). This can at times cause + problems, especially if userspace suspend scripts try to do things with the + console before or after suspending (e.g. calling vbestate). + + To work around this, enable this option so that PM will not handle the + console. + + If unsure, say N. + config SOFTWARE_SUSPEND bool "Software Suspend (Hibernation)" depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) --- linux-source-2.6.22-2.6.22.orig/kernel/power/snapshot.c +++ linux-source-2.6.22-2.6.22/kernel/power/snapshot.c @@ -709,7 +709,8 @@ region->end_pfn << PAGE_SHIFT); for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) - memory_bm_set_bit(bm, pfn); + if (pfn_valid(pfn)) + memory_bm_set_bit(bm, pfn); } } --- linux-source-2.6.22-2.6.22.orig/kernel/kmod.c +++ linux-source-2.6.22-2.6.22/kernel/kmod.c @@ -305,23 +305,32 @@ EXPORT_SYMBOL(call_usermodehelper_keys); int call_usermodehelper_pipe(char *path, char **argv, char **envp, - struct file **filp) + struct file **filp, struct subprocess_info **sub_info) { - DECLARE_COMPLETION(done); - struct subprocess_info sub_info = { - .work = __WORK_INITIALIZER(sub_info.work, - __call_usermodehelper), - .complete = &done, - .path = path, - .argv = argv, - .envp = envp, - .retval = 0, - }; struct file *f; + struct subprocess_info *sinfo; if (!khelper_wq) return -EBUSY; + sinfo = kzalloc(sizeof(struct subprocess_info), GFP_KERNEL); + if (!sinfo) + return -ENOMEM; + + sinfo->complete = kmalloc(sizeof(struct completion), GFP_KERNEL); + if (!sinfo->complete) { + kfree(sinfo); + return -ENOMEM; + } + + *sub_info = sinfo; + INIT_WORK(&sinfo->work, __call_usermodehelper); + init_completion(sinfo->complete); + sinfo->path = path; + sinfo->argv = argv; + sinfo->envp = envp; + sinfo->wait = 1; + if (path[0] == '\0') return 0; @@ -335,14 +344,23 @@ free_write_pipe(*filp); return PTR_ERR(f); } - sub_info.stdin = f; + sinfo->stdin = f; - queue_work(khelper_wq, &sub_info.work); - wait_for_completion(&done); - return sub_info.retval; + queue_work(khelper_wq, &sinfo->work); + return 0; } EXPORT_SYMBOL(call_usermodehelper_pipe); +int finish_usermodehelper_pipe(struct subprocess_info *sub_info) +{ + wait_for_completion(sub_info->complete); + kfree(sub_info->complete); + kfree(sub_info); + + return sub_info->retval; +} +EXPORT_SYMBOL(finish_usermodehelper_pipe); + void __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); --- linux-source-2.6.22-2.6.22.orig/kernel/futex_compat.c +++ linux-source-2.6.22-2.6.22/kernel/futex_compat.c @@ -29,6 +29,15 @@ return 0; } +static void __user *futex_uaddr(struct robust_list *entry, + compat_long_t futex_offset) +{ + compat_uptr_t base = ptr_to_compat(entry); + void __user *uaddr = compat_ptr(base + futex_offset); + + return uaddr; +} + /* * Walk curr->robust_list (very carefully, it's a userspace list!) * and mark any locks found there dead, and notify any waiters. @@ -61,19 +70,23 @@ if (fetch_robust_entry(&upending, &pending, &head->list_op_pending, &pip)) return; - if (upending) - handle_futex_death((void __user *)pending + futex_offset, curr, pip); + if (pending) { + void __user *uaddr = futex_uaddr(pending, futex_offset); - while (compat_ptr(uentry) != &head->list) { + handle_futex_death(uaddr, curr, pip); + } + + while (entry != (struct robust_list __user *) &head->list) { /* * A pending lock might already be on the list, so * dont process it twice: */ - if (entry != pending) - if (handle_futex_death((void __user *)entry + futex_offset, - curr, pi)) + if (entry != pending) { + void __user *uaddr = futex_uaddr(entry, + futex_offset); + if (handle_futex_death(uaddr, curr, pi)) return; - + } /* * Fetch the next entry in the list: */ @@ -154,7 +167,7 @@ t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add(ktime_get(), t); + t = ktime_add_safe(ktime_get(), t); tp = &t; } if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) --- linux-source-2.6.22-2.6.22.orig/kernel/lockdep_proc.c +++ linux-source-2.6.22-2.6.22/kernel/lockdep_proc.c @@ -339,7 +339,7 @@ .open = lockdep_stats_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; static int __init lockdep_proc_init(void) --- linux-source-2.6.22-2.6.22.orig/kernel/posix-timers.c +++ linux-source-2.6.22-2.6.22/kernel/posix-timers.c @@ -764,9 +764,11 @@ /* SIGEV_NONE timers are not queued ! See common_timer_get */ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { /* Setup correct expiry time for relative timers */ - if (mode == HRTIMER_MODE_REL) - timer->expires = ktime_add(timer->expires, - timer->base->get_time()); + if (mode == HRTIMER_MODE_REL) { + timer->expires = + ktime_add_safe(timer->expires, + timer->base->get_time()); + } return 0; } --- linux-source-2.6.22-2.6.22.orig/kernel/audit.c +++ linux-source-2.6.22-2.6.22/kernel/audit.c @@ -1054,8 +1054,7 @@ * will be called a second time. Currently, we assume that a printk * can't format message larger than 1024 bytes, so we don't either. */ -static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, - va_list args) +void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args) { int len, avail; struct sk_buff *skb; @@ -1311,3 +1310,6 @@ EXPORT_SYMBOL(audit_log_end); EXPORT_SYMBOL(audit_log_format); EXPORT_SYMBOL(audit_log); +EXPORT_SYMBOL_GPL(audit_log_vformat); +EXPORT_SYMBOL_GPL(audit_log_untrustedstring); +EXPORT_SYMBOL_GPL(audit_log_d_path); --- linux-source-2.6.22-2.6.22.orig/kernel/hrtimer.c +++ linux-source-2.6.22-2.6.22/kernel/hrtimer.c @@ -305,6 +305,23 @@ } #endif /* BITS_PER_LONG >= 64 */ +/* + * Add two ktime values and do a safety check for overflow: + */ +ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) +{ + ktime_t res = ktime_add(lhs, rhs); + + /* + * We use KTIME_SEC_MAX here, the maximum timeout which we can + * return to user space in a timespec: + */ + if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) + res = ktime_set(KTIME_SEC_MAX, 0); + + return res; +} + /* High resolution timer related functions */ #ifdef CONFIG_HIGH_RES_TIMERS @@ -659,13 +676,7 @@ */ orun++; } - timer->expires = ktime_add(timer->expires, interval); - /* - * Make sure, that the result did not wrap with a very large - * interval. - */ - if (timer->expires.tv64 < 0) - timer->expires = ktime_set(KTIME_SEC_MAX, 0); + timer->expires = ktime_add_safe(timer->expires, interval); return orun; } @@ -814,7 +825,7 @@ new_base = switch_hrtimer_base(timer, base); if (mode == HRTIMER_MODE_REL) { - tim = ktime_add(tim, new_base->get_time()); + tim = ktime_add_safe(tim, new_base->get_time()); /* * CONFIG_TIME_LOW_RES is a temporary way for architectures * to signal that they simply return xtime in @@ -823,7 +834,7 @@ * timeouts. This will go away with the GTOD framework. */ #ifdef CONFIG_TIME_LOW_RES - tim = ktime_add(tim, base->resolution); + tim = ktime_add_safe(tim, base->resolution); #endif } timer->expires = tim; @@ -1406,7 +1417,7 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { - long cpu = (long)hcpu; + unsigned int cpu = (long)hcpu; switch (action) { --- linux-source-2.6.22-2.6.22.orig/kernel/auditsc.c +++ linux-source-2.6.22-2.6.22/kernel/auditsc.c @@ -1998,19 +1998,19 @@ extern uid_t audit_sig_uid; extern u32 audit_sig_sid; - if (audit_pid && t->tgid == audit_pid && - (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1)) { - audit_sig_pid = tsk->pid; - if (ctx) - audit_sig_uid = ctx->loginuid; - else - audit_sig_uid = tsk->uid; - selinux_get_task_sid(tsk, &audit_sig_sid); + if (audit_pid && t->tgid == audit_pid) { + if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { + audit_sig_pid = tsk->pid; + if (ctx) + audit_sig_uid = ctx->loginuid; + else + audit_sig_uid = tsk->uid; + selinux_get_task_sid(tsk, &audit_sig_sid); + } + if (!audit_signals || audit_dummy_context()) + return 0; } - if (!audit_signals) /* audit_context checked in wrapper */ - return 0; - /* optimize the common case by putting first signal recipient directly * in audit_context */ if (!ctx->target_pid) { --- linux-source-2.6.22-2.6.22.orig/kernel/sysctl.c +++ linux-source-2.6.22-2.6.22/kernel/sysctl.c @@ -1110,6 +1110,33 @@ return NULL; } +char *sysctl_pathname(ctl_table *table, char *buffer, int buflen) +{ + if (buflen < 1) + return NULL; + buffer += --buflen; + *buffer = '\0'; + + while (table) { + int namelen = strlen(table->procname); + + if (buflen < namelen + 1) + return NULL; + buflen -= namelen + 1; + buffer -= namelen; + memcpy(buffer, table->procname, namelen); + *--buffer = '/'; + table = table->parent; + } + if (buflen < 4) + return NULL; + buffer -= 4; + memcpy(buffer, "/sys", 4); + + return buffer; +} +EXPORT_SYMBOL(sysctl_pathname); + #ifdef CONFIG_SYSCTL_SYSCALL int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) --- linux-source-2.6.22-2.6.22.orig/kernel/time/tick-broadcast.c +++ linux-source-2.6.22-2.6.22/kernel/time/tick-broadcast.c @@ -364,11 +364,7 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc) { clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); - - if(!cpus_empty(tick_broadcast_oneshot_mask)) - tick_broadcast_set_event(ktime_get(), 1); - - return cpu_isset(smp_processor_id(), tick_broadcast_oneshot_mask); + return 0; } /* --- linux-source-2.6.22-2.6.22.orig/kernel/time/timer_stats.c +++ linux-source-2.6.22-2.6.22/kernel/time/timer_stats.c @@ -391,7 +391,7 @@ .read = seq_read, .write = tstats_write, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; void __init init_timer_stats(void) --- linux-source-2.6.22-2.6.22.orig/kernel/time/timer_list.c +++ linux-source-2.6.22-2.6.22/kernel/time/timer_list.c @@ -267,7 +267,7 @@ .open = timer_list_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; static int __init init_timer_list_procfs(void) --- linux-source-2.6.22-2.6.22.orig/kernel/workqueue.c +++ linux-source-2.6.22-2.6.22/kernel/workqueue.c @@ -739,18 +739,17 @@ if (cwq->thread == NULL) return; + flush_cpu_workqueue(cwq); /* - * If the caller is CPU_DEAD the single flush_cpu_workqueue() - * is not enough, a concurrent flush_workqueue() can insert a - * barrier after us. + * If the caller is CPU_DEAD and cwq->worklist was not empty, + * a concurrent flush_workqueue() can insert a barrier after us. + * However, in that case run_workqueue() won't return and check + * kthread_should_stop() until it flushes all work_struct's. * When ->worklist becomes empty it is safe to exit because no * more work_structs can be queued on this cwq: flush_workqueue * checks list_empty(), and a "normal" queue_work() can't use * a dead CPU. */ - while (flush_cpu_workqueue(cwq)) - ; - kthread_stop(cwq->thread); cwq->thread = NULL; } --- linux-source-2.6.22-2.6.22.orig/kernel/futex.c +++ linux-source-2.6.22-2.6.22/kernel/futex.c @@ -2056,13 +2056,15 @@ t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add(ktime_get(), t); + t = ktime_add_safe(ktime_get(), t); tp = &t; } /* * requeue parameter in 'utime' if cmd == FUTEX_REQUEUE. + * number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP. */ - if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) + if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE || + cmd == FUTEX_WAKE_OP) val2 = (u32) (unsigned long) utime; return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); --- linux-source-2.6.22-2.6.22.orig/arch/i386/Makefile +++ linux-source-2.6.22-2.6.22/arch/i386/Makefile @@ -51,8 +51,8 @@ CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) --- linux-source-2.6.22-2.6.22.orig/arch/i386/Kconfig.debug +++ linux-source-2.6.22-2.6.22/arch/i386/Kconfig.debug @@ -19,6 +19,12 @@ with klogd/syslogd or the X server. You should normally N here, unless you want to debug such a crash. +config WRAPPER_PRINT + bool "Boot wrapper print" if EMBEDDED + default y + help + Enable informational output from the bootwrapper (bzImage and zImage). + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL --- linux-source-2.6.22-2.6.22.orig/arch/i386/mm/fault.c +++ linux-source-2.6.22-2.6.22/arch/i386/mm/fault.c @@ -249,9 +249,10 @@ pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) return NULL; - if (!pmd_present(*pmd)) + if (!pmd_present(*pmd)) { set_pmd(pmd, *pmd_k); - else + arch_flush_lazy_mmu_mode(); + } else BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); return pmd_k; } --- linux-source-2.6.22-2.6.22.orig/arch/i386/pci/common.c +++ linux-source-2.6.22-2.6.22/arch/i386/pci/common.c @@ -17,8 +17,7 @@ #include "pci.h" -unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | - PCI_PROBE_MMCONF; +unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; static int pci_bf_sort; int pci_routeirq; @@ -145,6 +144,22 @@ } #endif +#ifdef CONFIG_PCI_MMCONFIG +static int __devinit working_mmconfig(struct dmi_system_id *d) +{ + pci_probe |= PCI_PROBE_MMCONF; + return 0; +} + +static int __devinit blacklist_mmconfig(struct dmi_system_id *d) +{ + pci_probe &= ~PCI_PROBE_MMCONF; + printk(KERN_INFO "%s detected: disabling MMCONFIG PCI access", + d->ident); + return 0; +} +#endif /*CONFIG_PCI_MMCONFIG*/ + static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { #ifdef __i386__ /* @@ -388,6 +403,10 @@ pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } + else if (!strcmp(str, "mmconf")) { + pci_probe |= PCI_PROBE_MMCONF; + return NULL; + } #endif else if (!strcmp(str, "noacpi")) { acpi_noirq_set(); --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/acpi/boot.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/acpi/boot.c @@ -592,9 +592,25 @@ * RSDP signature. */ for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); + if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len) == 0) { + /* 2007-09-24 TJ + * The ACPI specification states the first 20 bytes of the RSDP table + * must have a checksum of 0 (ACPI 1.0b RSDP table is 20 bytes long). + * The signature can appear in multiple memory locations so don't rely + * on it as the sole proof of a valid table. + * This fixes broken/disabled ACPI problems with Acer Travelmate C100 + * (and others) where the first signature match is accepted without + * confirming the checksum. + */ + unsigned int i; + unsigned char checksum; + unsigned char *table = (unsigned char *)(phys_to_virt(start) + offset); + for (checksum = 0, i = 0; i < 20; i++) + checksum += table[i]; + + printk(KERN_WARNING PREFIX "RSDP signature @ 0x%0.8lX checksum %d\n", table, checksum); + if (checksum == 0) return (start + offset); + } } return 0; --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/Makefile +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o -obj-$(CONFIG_SERIAL_8250) += legacy_serial.o obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/doublefault.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/doublefault.c @@ -13,7 +13,7 @@ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) -#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000) +#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) static void doublefault_fn(void) { @@ -23,23 +23,23 @@ store_gdt(&gdt_desc); gdt = gdt_desc.address; - printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); if (ptr_ok(gdt)) { gdt += GDT_ENTRY_TSS << 3; tss = *(u16 *)(gdt+2); tss += *(u8 *)(gdt+4) << 16; tss += *(u8 *)(gdt+7) << 24; - printk("double fault, tss at %08lx\n", tss); + printk(KERN_EMERG "double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { struct i386_hw_tss *t = (struct i386_hw_tss *)tss; - printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); + printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp); - printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", + printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", t->eax, t->ebx, t->ecx, t->edx); - printk("esi = %08lx, edi = %08lx\n", + printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", t->esi, t->edi); } } @@ -63,6 +63,7 @@ .cs = __KERNEL_CS, .ss = __KERNEL_DS, .ds = __USER_DS, + .fs = __KERNEL_PERCPU, .__cr3 = __pa(swapper_pg_dir) } --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/sysenter.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/sysenter.c @@ -336,7 +336,9 @@ int in_gate_area(struct task_struct *task, unsigned long addr) { - return 0; + const struct vm_area_struct *vma = get_gate_vma(task); + + return vma && addr >= vma->vm_start && addr < vma->vm_end; } int in_gate_area_no_task(unsigned long addr) --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/hpet.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/hpet.c @@ -226,7 +226,8 @@ { unsigned long id; uint64_t hpet_freq; - u64 tmp; + u64 tmp, start, now; + cycle_t t1; if (!is_hpet_capable()) return 0; @@ -273,6 +274,27 @@ /* Start the counter */ hpet_start_counter(); + /* Verify whether hpet counter works */ + t1 = read_hpet(); + rdtscll(start); + + /* + * We don't know the TSC frequency yet, but waiting for + * 200000 TSC cycles is safe: + * 4 GHz == 50us + * 1 GHz == 200us + */ + do { + rep_nop(); + rdtscll(now); + } while ((now - start) < 200000UL); + + if (t1 == read_hpet()) { + printk(KERN_WARNING + "HPET counter not counting. HPET disabled\n"); + goto out_nohpet; + } + /* Initialize and register HPET clocksource * * hpet period is in femto seconds per cycle --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/cpu/perfctr-watchdog.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/cpu/perfctr-watchdog.c @@ -346,7 +346,9 @@ perfctr_msr = MSR_P6_PERFCTR0; evntsel_msr = MSR_P6_EVNTSEL0; - wrmsrl(perfctr_msr, 0UL); + /* KVM doesn't implement this MSR */ + if (wrmsr_safe(perfctr_msr, 0, 0) < 0) + return 0; evntsel = P6_EVNTSEL_INT | P6_EVNTSEL_OS --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -76,7 +76,10 @@ /* Return a frequency in MHz, given an input fid and did */ static u32 find_freq_from_fiddid(u32 fid, u32 did) { - return 100 * (fid + 0x10) >> did; + if (current_cpu_data.x86 == 0x10) + return 100 * (fid + 0x10) >> did; + else + return 100 * (fid + 0x8) >> did; } static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -167,11 +167,13 @@ static void do_drv_write(struct drv_cmd *cmd) { - u32 h = 0; + u32 lo, hi; switch (cmd->type) { case SYSTEM_INTEL_MSR_CAPABLE: - wrmsr(cmd->addr.msr.reg, cmd->val, h); + rdmsr(cmd->addr.msr.reg, lo, hi); + lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE); + wrmsr(cmd->addr.msr.reg, lo, hi); break; case SYSTEM_IO_CAPABLE: acpi_os_write_port((acpi_io_address)cmd->addr.io.port, @@ -372,7 +374,6 @@ struct cpufreq_freqs freqs; cpumask_t online_policy_cpus; struct drv_cmd cmd; - unsigned int msr; unsigned int next_state = 0; /* Index into freq_table */ unsigned int next_perf_state = 0; /* Index into perf table */ unsigned int i; @@ -417,11 +418,7 @@ case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; cmd.addr.msr.reg = MSR_IA32_PERF_CTL; - msr = - (u32) perf->states[next_perf_state]. - control & INTEL_MSR_RANGE; - cmd.val = get_cur_val(online_policy_cpus); - cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr; + cmd.val = (u32) perf->states[next_perf_state].control; break; case SYSTEM_IO_CAPABLE: cmd.type = SYSTEM_IO_CAPABLE; --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/cpu/amd.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/cpu/amd.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "cpu.h" @@ -22,6 +23,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); +#ifdef CONFIG_X86_LOCAL_APIC #define ENABLE_C1E_MASK 0x18000000 #define CPUID_PROCESSOR_SIGNATURE 1 #define CPUID_XFAM 0x0ff00000 @@ -52,6 +54,7 @@ } return 0; } +#endif int force_mwait __cpuinitdata; @@ -275,8 +278,10 @@ if (cpuid_eax(0x80000000) >= 0x80000006) num_cache_leaves = 3; +#ifdef CONFIG_X86_LOCAL_APIC if (amd_apic_timer_broken()) - set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); + local_apic_timer_disabled = 1; +#endif if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, c->x86_capability); --- linux-source-2.6.22-2.6.22.orig/arch/i386/kernel/apic.c +++ linux-source-2.6.22-2.6.22/arch/i386/kernel/apic.c @@ -61,8 +61,9 @@ /* Local APIC timer verification ok */ static int local_apic_timer_verify_ok; -/* Disable local APIC timer from the kernel commandline or via dmi quirk */ -static int local_apic_timer_disabled; +/* Disable local APIC timer from the kernel commandline or via dmi quirk + or using CPU MSR check */ +int local_apic_timer_disabled; /* Local APIC timer works in C2 */ int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); @@ -367,9 +368,6 @@ long delta, deltapm; int pm_referenced = 0; - if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) - local_apic_timer_disabled = 1; - /* * The local apic timer can be disabled via the kernel * commandline or from the test above. Register the lapic --- linux-source-2.6.22-2.6.22.orig/arch/i386/boot/compressed/misc.c +++ linux-source-2.6.22-2.6.22/arch/i386/boot/compressed/misc.c @@ -184,8 +184,6 @@ static void *memset(void *s, int c, unsigned n); static void *memcpy(void *dest, const void *src, unsigned n); -static void putstr(const char *); - static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; @@ -232,7 +230,8 @@ { free_mem_ptr = (unsigned long) *ptr; } - + +#ifdef CONFIG_WRAPPER_PRINT static void scroll(void) { int i; @@ -278,6 +277,9 @@ outb_p(15, vidport); outb_p(0xff & (pos >> 1), vidport+1); } +#else +#define putstr(__x) do{}while(0) +#endif /* CONFIG_WRAPPER_PRINT */ static void* memset(void* s, int c, unsigned n) { --- linux-source-2.6.22-2.6.22.orig/arch/ia64/kernel/unaligned.c +++ linux-source-2.6.22-2.6.22/arch/ia64/kernel/unaligned.c @@ -1487,16 +1487,19 @@ case LDFA_OP: case LDFCCLR_OP: case LDFCNC_OP: - case LDF_IMM_OP: - case LDFA_IMM_OP: - case LDFCCLR_IMM_OP: - case LDFCNC_IMM_OP: if (u.insn.x) ret = emulate_load_floatpair(ifa, u.insn, regs); else ret = emulate_load_float(ifa, u.insn, regs); break; + case LDF_IMM_OP: + case LDFA_IMM_OP: + case LDFCCLR_IMM_OP: + case LDFCNC_IMM_OP: + ret = emulate_load_float(ifa, u.insn, regs); + break; + case STF_OP: case STF_IMM_OP: ret = emulate_store_float(ifa, u.insn, regs); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/mm/init.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/mm/init.c @@ -1135,14 +1135,9 @@ } } -static void __init kernel_physical_mapping_init(void) +static void __init init_kpte_bitmap(void) { unsigned long i; -#ifdef CONFIG_DEBUG_PAGEALLOC - unsigned long mem_alloced = 0UL; -#endif - - read_obp_memory("reg", &pall[0], &pall_ents); for (i = 0; i < pall_ents; i++) { unsigned long phys_start, phys_end; @@ -1151,14 +1146,24 @@ phys_end = phys_start + pall[i].reg_size; mark_kpte_bitmap(phys_start, phys_end); + } +} +static void __init kernel_physical_mapping_init(void) +{ #ifdef CONFIG_DEBUG_PAGEALLOC + unsigned long i, mem_alloced = 0UL; + + for (i = 0; i < pall_ents; i++) { + unsigned long phys_start, phys_end; + + phys_start = pall[i].phys_addr; + phys_end = phys_start + pall[i].reg_size; + mem_alloced += kernel_map_range(phys_start, phys_end, PAGE_KERNEL); -#endif } -#ifdef CONFIG_DEBUG_PAGEALLOC printk("Allocated %ld bytes for kernel page tables.\n", mem_alloced); @@ -1400,6 +1405,10 @@ inherit_prom_mappings(); + read_obp_memory("reg", &pall[0], &pall_ents); + + init_kpte_bitmap(); + /* Ok, we can use our TLB miss and window trap handlers safely. */ setup_tba(); @@ -1854,7 +1863,9 @@ "wrpr %0, %1, %%pstate" : "=r" (pstate) : "i" (PSTATE_IE)); - if (tlb_type == spitfire) { + if (tlb_type == hypervisor) { + sun4v_mmu_demap_all(); + } else if (tlb_type == spitfire) { for (i = 0; i < 64; i++) { /* Spitfire Errata #32 workaround */ /* NOTE: Always runs on spitfire, so no --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/mm/fault.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/mm/fault.c @@ -112,15 +112,12 @@ static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) { - unsigned long *ksp; - printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", regs->tpc); printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]); print_symbol("RPC: <%s>\n", regs->u_regs[15]); printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr); - __asm__("mov %%sp, %0" : "=r" (ksp)); - show_stack(current, ksp); + dump_stack(); unhandled_fault(regs->tpc, current, regs); } --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/prom/console.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/prom/console.c @@ -73,88 +73,3 @@ P1275_INOUT(3,1), prom_stdout, s, P1275_SIZE(len)); } - -/* Query for input device type */ -enum prom_input_device -prom_query_input_device(void) -{ - int st_p; - char propb[64]; - - st_p = prom_inst2pkg(prom_stdin); - if(prom_node_has_property(st_p, "keyboard")) - return PROMDEV_IKBD; - prom_getproperty(st_p, "device_type", propb, sizeof(propb)); - if(strncmp(propb, "serial", 6)) - return PROMDEV_I_UNK; - /* FIXME: Is there any better way how to find out? */ - memset(propb, 0, sizeof(propb)); - st_p = prom_finddevice ("/options"); - prom_getproperty(st_p, "input-device", propb, sizeof(propb)); - - /* - * If we get here with propb == 'keyboard', we are on ttya, as - * the PROM defaulted to this due to 'no input device'. - */ - if (!strncmp(propb, "keyboard", 8)) - return PROMDEV_ITTYA; - - if (!strncmp (propb, "rsc", 3)) - return PROMDEV_IRSC; - - if (!strncmp (propb, "virtual-console", 3)) - return PROMDEV_IVCONS; - - if (strncmp (propb, "tty", 3) || !propb[3]) - return PROMDEV_I_UNK; - - switch (propb[3]) { - case 'a': return PROMDEV_ITTYA; - case 'b': return PROMDEV_ITTYB; - default: return PROMDEV_I_UNK; - } -} - -/* Query for output device type */ - -enum prom_output_device -prom_query_output_device(void) -{ - int st_p; - char propb[64]; - int propl; - - st_p = prom_inst2pkg(prom_stdout); - propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); - if (propl >= 0 && propl == sizeof("display") && - strncmp("display", propb, sizeof("display")) == 0) - return PROMDEV_OSCREEN; - if(strncmp("serial", propb, 6)) - return PROMDEV_O_UNK; - /* FIXME: Is there any better way how to find out? */ - memset(propb, 0, sizeof(propb)); - st_p = prom_finddevice ("/options"); - prom_getproperty(st_p, "output-device", propb, sizeof(propb)); - - /* - * If we get here with propb == 'screen', we are on ttya, as - * the PROM defaulted to this due to 'no input device'. - */ - if (!strncmp(propb, "screen", 6)) - return PROMDEV_OTTYA; - - if (!strncmp (propb, "rsc", 3)) - return PROMDEV_ORSC; - - if (!strncmp (propb, "virtual-console", 3)) - return PROMDEV_OVCONS; - - if (strncmp (propb, "tty", 3) || !propb[3]) - return PROMDEV_O_UNK; - - switch (propb[3]) { - case 'a': return PROMDEV_OTTYA; - case 'b': return PROMDEV_OTTYB; - default: return PROMDEV_O_UNK; - } -} --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/prom/tree.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/prom/tree.c @@ -13,6 +13,7 @@ #include #include +#include /* Return the child of node 'node' or zero if no this node has no * direct descendent. @@ -261,9 +262,17 @@ int prom_setprop(int node, const char *pname, char *value, int size) { - if(size == 0) return 0; - if((pname == 0) || (value == 0)) return 0; + if (size == 0) + return 0; + if ((pname == 0) || (value == 0)) + return 0; +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) { + ldom_set_var(pname, value); + return 0; + } +#endif return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| P1275_ARG(2,P1275_ARG_IN_BUF)| P1275_INOUT(4, 1), @@ -295,3 +304,11 @@ if (node == -1) return 0; return node; } + +int prom_ihandle2path(int handle, char *buffer, int bufsize) +{ + return p1275_cmd("instance-to-path", + P1275_ARG(1,P1275_ARG_OUT_BUF)| + P1275_INOUT(3, 1), + handle, buffer, P1275_SIZE(bufsize)); +} --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/prom/p1275.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/prom/p1275.c @@ -16,6 +16,7 @@ #include #include #include +#include struct { long prom_callback; /* 0x00 */ --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/prom/misc.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/prom/misc.c @@ -14,6 +14,7 @@ #include #include #include +#include int prom_service_exists(const char *service_name) { @@ -37,6 +38,10 @@ /* Reset and reboot the machine with the command 'bcommand'. */ void prom_reboot(const char *bcommand) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_reboot(bcommand); +#endif p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | P1275_INOUT(1, 0), bcommand); } @@ -67,7 +72,7 @@ local_irq_save(flags); - if (!serial_console && prom_palette) + if (prom_palette) prom_palette(1); #ifdef CONFIG_SMP @@ -80,7 +85,7 @@ smp_release(); #endif - if (!serial_console && prom_palette) + if (prom_palette) prom_palette(0); local_irq_restore(flags); @@ -91,6 +96,10 @@ */ void prom_halt(void) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_power_off(); +#endif again: p1275_cmd("exit", P1275_INOUT(0, 0)); goto again; /* PROM is out to get me -DaveM */ @@ -98,6 +107,10 @@ void prom_halt_power_off(void) { +#ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) + ldom_power_off(); +#endif p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); /* if nothing else helps, we just halt */ @@ -130,22 +143,6 @@ return 0xff; } -/* Install Linux trap table so PROM uses that instead of its own. */ -void prom_set_trap_table(unsigned long tba) -{ - p1275_cmd("SUNW,set-trap-table", - (P1275_ARG(0, P1275_ARG_IN_64B) | - P1275_INOUT(1, 0)), tba); -} - -void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa) -{ - p1275_cmd("SUNW,set-trap-table", - (P1275_ARG(0, P1275_ARG_IN_64B) | - P1275_ARG(1, P1275_ARG_IN_64B) | - P1275_INOUT(2, 0)), tba, mmfsa); -} - int prom_get_mmu_ihandle(void) { int node, ret; --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/sysfs.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/sysfs.c @@ -193,7 +193,6 @@ } SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); -SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val); SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); @@ -203,7 +202,6 @@ static struct sysdev_attribute cpu_core_attrs[] = { _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), - _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL), _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/head.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/head.S @@ -97,7 +97,8 @@ .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache .globl prom_boot_mapped_pc, prom_boot_mapping_mode .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low - .globl is_sun4v + .globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible + .globl is_sun4v, sun4v_chip_type, prom_set_trap_table_name prom_peer_name: .asciz "peer" prom_compatible_name: @@ -106,6 +107,8 @@ .asciz "finddevice" prom_chosen_path: .asciz "/chosen" +prom_cpu_path: + .asciz "/cpu" prom_getprop_name: .asciz "getprop" prom_mmu_name: @@ -118,11 +121,17 @@ .asciz "map" prom_unmap_name: .asciz "unmap" +prom_set_trap_table_name: + .asciz "SUNW,set-trap-table" prom_sun4v_name: .asciz "sun4v" +prom_niagara_prefix: + .asciz "SUNW,UltraSPARC-T" .align 4 prom_root_compatible: .skip 64 +prom_cpu_compatible: + .skip 64 prom_root_node: .word 0 prom_mmu_ihandle_cache: @@ -138,6 +147,8 @@ .xword 0 is_sun4v: .word 0 +sun4v_chip_type: + .word SUN4V_CHIP_INVALID 1: rd %pc, %l0 @@ -296,13 +307,13 @@ sethi %hi(prom_sun4v_name), %g7 or %g7, %lo(prom_sun4v_name), %g7 mov 5, %g3 -1: ldub [%g7], %g2 +90: ldub [%g7], %g2 ldub [%g1], %g4 cmp %g2, %g4 - bne,pn %icc, 2f + bne,pn %icc, 80f add %g7, 1, %g7 subcc %g3, 1, %g3 - bne,pt %xcc, 1b + bne,pt %xcc, 90b add %g1, 1, %g1 sethi %hi(is_sun4v), %g1 @@ -310,7 +321,80 @@ mov 1, %g7 stw %g7, [%g1] -2: + /* cpu_node = prom_finddevice("/cpu") */ + mov (1b - prom_finddev_name), %l1 + mov (1b - prom_cpu_path), %l2 + sub %l0, %l1, %l1 + sub %l0, %l2, %l2 + sub %sp, (192 + 128), %sp + + stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" + mov 1, %l3 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 + stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/cpu" + stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 + call %l7 + add %sp, (2047 + 128), %o0 ! argument array + + ldx [%sp + 2047 + 128 + 0x20], %l4 ! cpu device node + + mov (1b - prom_getprop_name), %l1 + mov (1b - prom_compatible_name), %l2 + mov (1b - prom_cpu_compatible), %l5 + sub %l0, %l1, %l1 + sub %l0, %l2, %l2 + sub %l0, %l5, %l5 + + /* prom_getproperty(cpu_node, "compatible", + * &prom_cpu_compatible, 64) + */ + stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" + mov 4, %l3 + stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 + mov 1, %l3 + stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 + stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, cpu_node + stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible" + stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_cpu_compatible + mov 64, %l3 + stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size + stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 + call %l7 + add %sp, (2047 + 128), %o0 ! argument array + + add %sp, (192 + 128), %sp + + sethi %hi(prom_cpu_compatible), %g1 + or %g1, %lo(prom_cpu_compatible), %g1 + sethi %hi(prom_niagara_prefix), %g7 + or %g7, %lo(prom_niagara_prefix), %g7 + mov 17, %g3 +90: ldub [%g7], %g2 + ldub [%g1], %g4 + cmp %g2, %g4 + bne,pn %icc, 4f + add %g7, 1, %g7 + subcc %g3, 1, %g3 + bne,pt %xcc, 90b + add %g1, 1, %g1 + + sethi %hi(prom_cpu_compatible), %g1 + or %g1, %lo(prom_cpu_compatible), %g1 + ldub [%g1 + 17], %g2 + cmp %g2, '1' + be,pt %xcc, 5f + mov SUN4V_CHIP_NIAGARA1, %g4 + cmp %g2, '2' + be,pt %xcc, 5f + mov SUN4V_CHIP_NIAGARA2, %g4 +4: + mov SUN4V_CHIP_UNKNOWN, %g4 +5: sethi %hi(sun4v_chip_type), %g2 + or %g2, %lo(sun4v_chip_type), %g2 + stw %g4, [%g2] + +80: BRANCH_IF_SUN4V(g1, jump_to_sun4u_init) BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) @@ -413,6 +497,33 @@ stw %g2, [%g1 + %lo(tlb_type)] /* Patch copy/clear ops. */ + sethi %hi(sun4v_chip_type), %g1 + lduw [%g1 + %lo(sun4v_chip_type)], %g1 + cmp %g1, SUN4V_CHIP_NIAGARA1 + be,pt %xcc, niagara_patch + cmp %g1, SUN4V_CHIP_NIAGARA2 + be,pt %xcc, niagara2_patch + nop + + call generic_patch_copyops + nop + call generic_patch_bzero + nop + call generic_patch_pageops + nop + + ba,a,pt %xcc, 80f +niagara2_patch: + call niagara2_patch_copyops + nop + call niagara_patch_bzero + nop + call niagara2_patch_pageops + nop + + ba,a,pt %xcc, 80f + +niagara_patch: call niagara_patch_copyops nop call niagara_patch_bzero @@ -420,6 +531,7 @@ call niagara_patch_pageops nop +80: /* Patch TLB/cache ops. */ call hypervisor_patch_cachetlbops nop @@ -458,7 +570,6 @@ or %g6, %lo(init_thread_union), %g6 ldx [%g6 + TI_TASK], %g4 mov %sp, %l6 - mov %o4, %l7 wr %g0, ASI_P, %asi mov 1, %g1 @@ -579,15 +690,38 @@ sethi %hi(kern_base), %g3 ldx [%g3 + %lo(kern_base)], %g3 add %g2, %g3, %o1 + sethi %hi(sparc64_ttable_tl0), %o0 - call prom_set_trap_table_sun4v - sethi %hi(sparc64_ttable_tl0), %o0 + set prom_set_trap_table_name, %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 2, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 0, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + stx %o0, [%sp + 2047 + 128 + 0x18] + stx %o1, [%sp + 2047 + 128 + 0x20] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 ba,pt %xcc, 2f nop -1: call prom_set_trap_table - sethi %hi(sparc64_ttable_tl0), %o0 +1: sethi %hi(sparc64_ttable_tl0), %o0 + set prom_set_trap_table_name, %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 1, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 0, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + stx %o0, [%sp + 2047 + 128 + 0x18] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 /* Start using proper page size encodings in ctx register. */ 2: sethi %hi(sparc64_kern_pri_context), %g3 @@ -603,12 +737,13 @@ membar #Sync + BRANCH_IF_SUN4V(o2, 1f) + /* Kill PROM timer */ sethi %hi(0x80000000), %o2 sllx %o2, 32, %o2 wr %o2, 0, %tick_cmpr - BRANCH_IF_SUN4V(o2, 1f) BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) ba,pt %xcc, 2f --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/time.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/time.c @@ -849,9 +849,6 @@ { struct device_node *dp; unsigned long clock; -#ifdef CONFIG_SMP - extern void smp_tick_init(void); -#endif dp = of_find_node_by_path("/"); if (tlb_type == spitfire) { @@ -874,10 +871,6 @@ clock = of_getintprop_default(dp, "stick-frequency", 0); } -#ifdef CONFIG_SMP - smp_tick_init(); -#endif - return clock; } @@ -1038,10 +1031,31 @@ sparc64_clockevent.mult = mult; } +static unsigned long tb_ticks_per_usec __read_mostly; + +void __delay(unsigned long loops) +{ + unsigned long bclock, now; + + bclock = tick_ops->get_tick(); + do { + now = tick_ops->get_tick(); + } while ((now-bclock) < loops); +} +EXPORT_SYMBOL(__delay); + +void udelay(unsigned long usecs) +{ + __delay(tb_ticks_per_usec * usecs); +} +EXPORT_SYMBOL(udelay); + void __init time_init(void) { unsigned long clock = sparc64_init_timers(); + tb_ticks_per_usec = clock / USEC_PER_SEC; + timer_ticks_per_nsec_quotient = clocksource_hz2mult(clock, SPARC64_NSEC_PER_CYC_SHIFT); @@ -1102,7 +1116,7 @@ * Not having a register set can lead to trouble. * Also starfire doesn't have a tod clock. */ - if (!mregs && !dregs & !bregs) + if (!mregs && !dregs && !bregs) return -1; if (mregs) { --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/viohs.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/viohs.c @@ -0,0 +1,822 @@ +/* viohs.c: LDOM Virtual I/O handshake helper layer. + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +int vio_ldc_send(struct vio_driver_state *vio, void *data, int len) +{ + int err, limit = 1000; + + err = -EINVAL; + while (limit-- > 0) { + err = ldc_write(vio->lp, data, len); + if (!err || (err != -EAGAIN)) + break; + udelay(1); + } + + return err; +} +EXPORT_SYMBOL(vio_ldc_send); + +static int send_ctrl(struct vio_driver_state *vio, + struct vio_msg_tag *tag, int len) +{ + tag->sid = vio_send_sid(vio); + return vio_ldc_send(vio, tag, len); +} + +static void init_tag(struct vio_msg_tag *tag, u8 type, u8 stype, u16 stype_env) +{ + tag->type = type; + tag->stype = stype; + tag->stype_env = stype_env; +} + +static int send_version(struct vio_driver_state *vio, u16 major, u16 minor) +{ + struct vio_ver_info pkt; + + vio->_local_sid = (u32) sched_clock(); + + memset(&pkt, 0, sizeof(pkt)); + init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_VER_INFO); + pkt.major = major; + pkt.minor = minor; + pkt.dev_class = vio->dev_class; + + viodbg(HS, "SEND VERSION INFO maj[%u] min[%u] devclass[%u]\n", + major, minor, vio->dev_class); + + return send_ctrl(vio, &pkt.tag, sizeof(pkt)); +} + +static int start_handshake(struct vio_driver_state *vio) +{ + int err; + + viodbg(HS, "START HANDSHAKE\n"); + + vio->hs_state = VIO_HS_INVALID; + + err = send_version(vio, + vio->ver_table[0].major, + vio->ver_table[0].minor); + if (err < 0) + return err; + + return 0; +} + +static void flush_rx_dring(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr; + u64 ident; + + BUG_ON(!(vio->dr_state & VIO_DR_STATE_RXREG)); + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + ident = dr->ident; + + BUG_ON(!vio->desc_buf); + kfree(vio->desc_buf); + vio->desc_buf = NULL; + + memset(dr, 0, sizeof(*dr)); + dr->ident = ident; +} + +void vio_link_state_change(struct vio_driver_state *vio, int event) +{ + if (event == LDC_EVENT_UP) { + vio->hs_state = VIO_HS_INVALID; + + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + vio->dr_state = (VIO_DR_STATE_TXREQ | + VIO_DR_STATE_RXREQ); + break; + + case VDEV_DISK: + vio->dr_state = VIO_DR_STATE_TXREQ; + break; + case VDEV_DISK_SERVER: + vio->dr_state = VIO_DR_STATE_RXREQ; + break; + } + start_handshake(vio); + } else if (event == LDC_EVENT_RESET) { + vio->hs_state = VIO_HS_INVALID; + + if (vio->dr_state & VIO_DR_STATE_RXREG) + flush_rx_dring(vio); + + vio->dr_state = 0x00; + memset(&vio->ver, 0, sizeof(vio->ver)); + + ldc_disconnect(vio->lp); + } +} +EXPORT_SYMBOL(vio_link_state_change); + +static int handshake_failure(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr; + + /* XXX Put policy here... Perhaps start a timer to fire + * XXX in 100 ms, which will bring the link up and retry + * XXX the handshake. + */ + + viodbg(HS, "HANDSHAKE FAILURE\n"); + + vio->dr_state &= ~(VIO_DR_STATE_TXREG | + VIO_DR_STATE_RXREG); + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + memset(dr, 0, sizeof(*dr)); + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; + + vio->hs_state = VIO_HS_INVALID; + + return -ECONNRESET; +} + +static int process_unknown(struct vio_driver_state *vio, void *arg) +{ + struct vio_msg_tag *pkt = arg; + + viodbg(HS, "UNKNOWN CONTROL [%02x:%02x:%04x:%08x]\n", + pkt->type, pkt->stype, pkt->stype_env, pkt->sid); + + printk(KERN_ERR "vio: ID[%lu] Resetting connection.\n", + vio->vdev->channel_id); + + ldc_disconnect(vio->lp); + + return -ECONNRESET; +} + +static int send_dreg(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_TX_RING]; + union { + struct vio_dring_register pkt; + char all[sizeof(struct vio_dring_register) + + (sizeof(struct ldc_trans_cookie) * + dr->ncookies)]; + } u; + int i; + + memset(&u, 0, sizeof(u)); + init_tag(&u.pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_DRING_REG); + u.pkt.dring_ident = 0; + u.pkt.num_descr = dr->num_entries; + u.pkt.descr_size = dr->entry_size; + u.pkt.options = VIO_TX_DRING; + u.pkt.num_cookies = dr->ncookies; + + viodbg(HS, "SEND DRING_REG INFO ndesc[%u] dsz[%u] opt[0x%x] " + "ncookies[%u]\n", + u.pkt.num_descr, u.pkt.descr_size, u.pkt.options, + u.pkt.num_cookies); + + for (i = 0; i < dr->ncookies; i++) { + u.pkt.cookies[i] = dr->cookies[i]; + + viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", + i, + (unsigned long long) u.pkt.cookies[i].cookie_addr, + (unsigned long long) u.pkt.cookies[i].cookie_size); + } + + return send_ctrl(vio, &u.pkt.tag, sizeof(u)); +} + +static int send_rdx(struct vio_driver_state *vio) +{ + struct vio_rdx pkt; + + memset(&pkt, 0, sizeof(pkt)); + + init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_RDX); + + viodbg(HS, "SEND RDX INFO\n"); + + return send_ctrl(vio, &pkt.tag, sizeof(pkt)); +} + +static int send_attr(struct vio_driver_state *vio) +{ + return vio->ops->send_attr(vio); +} + +static struct vio_version *find_by_major(struct vio_driver_state *vio, + u16 major) +{ + struct vio_version *ret = NULL; + int i; + + for (i = 0; i < vio->ver_table_entries; i++) { + struct vio_version *v = &vio->ver_table[i]; + if (v->major <= major) { + ret = v; + break; + } + } + return ret; +} + +static int process_ver_info(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + struct vio_version *vap; + int err; + + viodbg(HS, "GOT VERSION INFO maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if (vio->hs_state != VIO_HS_INVALID) { + /* XXX Perhaps invoke start_handshake? XXX */ + memset(&vio->ver, 0, sizeof(vio->ver)); + vio->hs_state = VIO_HS_INVALID; + } + + vap = find_by_major(vio, pkt->major); + + vio->_peer_sid = pkt->tag.sid; + + if (!vap) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + pkt->major = 0; + pkt->minor = 0; + viodbg(HS, "SEND VERSION NACK maj[0] min[0]\n"); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + } else if (vap->major != pkt->major) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + pkt->major = vap->major; + pkt->minor = vap->minor; + viodbg(HS, "SEND VERSION NACK maj[%u] min[%u]\n", + pkt->major, pkt->minor); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + } else { + struct vio_version ver = { + .major = pkt->major, + .minor = pkt->minor, + }; + if (ver.minor > vap->minor) + ver.minor = vap->minor; + pkt->minor = ver.minor; + pkt->tag.stype = VIO_SUBTYPE_ACK; + viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n", + pkt->major, pkt->minor); + err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + if (err > 0) { + vio->ver = ver; + vio->hs_state = VIO_HS_GOTVERS; + } + } + if (err < 0) + return handshake_failure(vio); + + return 0; +} + +static int process_ver_ack(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + viodbg(HS, "GOT VERSION ACK maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if (vio->hs_state & VIO_HS_GOTVERS) { + if (vio->ver.major != pkt->major || + vio->ver.minor != pkt->minor) { + pkt->tag.stype = VIO_SUBTYPE_NACK; + (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + return handshake_failure(vio); + } + } else { + vio->ver.major = pkt->major; + vio->ver.minor = pkt->minor; + vio->hs_state = VIO_HS_GOTVERS; + } + + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_DISK: + if (send_attr(vio) < 0) + return handshake_failure(vio); + break; + + default: + break; + } + + return 0; +} + +static int process_ver_nack(struct vio_driver_state *vio, + struct vio_ver_info *pkt) +{ + struct vio_version *nver; + + viodbg(HS, "GOT VERSION NACK maj[%u] min[%u] devclass[%u]\n", + pkt->major, pkt->minor, pkt->dev_class); + + if ((pkt->major == 0 && pkt->minor == 0) || + !(nver = find_by_major(vio, pkt->major))) + return handshake_failure(vio); + + if (send_version(vio, nver->major, nver->minor) < 0) + return handshake_failure(vio); + + return 0; +} + +static int process_ver(struct vio_driver_state *vio, struct vio_ver_info *pkt) +{ + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_ver_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_ver_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_ver_nack(vio, pkt); + + default: + return handshake_failure(vio); + }; +} + +static int process_attr(struct vio_driver_state *vio, void *pkt) +{ + int err; + + if (!(vio->hs_state & VIO_HS_GOTVERS)) + return handshake_failure(vio); + + err = vio->ops->handle_attr(vio, pkt); + if (err < 0) { + return handshake_failure(vio); + } else { + vio->hs_state |= VIO_HS_GOT_ATTR; + + if ((vio->dr_state & VIO_DR_STATE_TXREQ) && + !(vio->hs_state & VIO_HS_SENT_DREG)) { + if (send_dreg(vio) < 0) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_SENT_DREG; + } + } + return 0; +} + +static int all_drings_registered(struct vio_driver_state *vio) +{ + int need_rx, need_tx; + + need_rx = (vio->dr_state & VIO_DR_STATE_RXREQ); + need_tx = (vio->dr_state & VIO_DR_STATE_TXREQ); + + if (need_rx && + !(vio->dr_state & VIO_DR_STATE_RXREG)) + return 0; + + if (need_tx && + !(vio->dr_state & VIO_DR_STATE_TXREG)) + return 0; + + return 1; +} + +static int process_dreg_info(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + struct vio_dring_state *dr; + int i, len; + + viodbg(HS, "GOT DRING_REG INFO ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + if (!(vio->dr_state & VIO_DR_STATE_RXREQ)) + goto send_nack; + + if (vio->dr_state & VIO_DR_STATE_RXREG) + goto send_nack; + + BUG_ON(vio->desc_buf); + + vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); + if (!vio->desc_buf) + goto send_nack; + + vio->desc_buf_len = pkt->descr_size; + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + + dr->num_entries = pkt->num_descr; + dr->entry_size = pkt->descr_size; + dr->ncookies = pkt->num_cookies; + for (i = 0; i < dr->ncookies; i++) { + dr->cookies[i] = pkt->cookies[i]; + + viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", + i, + (unsigned long long) + pkt->cookies[i].cookie_addr, + (unsigned long long) + pkt->cookies[i].cookie_size); + } + + pkt->tag.stype = VIO_SUBTYPE_ACK; + pkt->dring_ident = ++dr->ident; + + viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n", + (unsigned long long) pkt->dring_ident); + + len = (sizeof(*pkt) + + (dr->ncookies * sizeof(struct ldc_trans_cookie))); + if (send_ctrl(vio, &pkt->tag, len) < 0) + goto send_nack; + + vio->dr_state |= VIO_DR_STATE_RXREG; + + return 0; + +send_nack: + pkt->tag.stype = VIO_SUBTYPE_NACK; + viodbg(HS, "SEND DRING_REG NACK\n"); + (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); + + return handshake_failure(vio); +} + +static int process_dreg_ack(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + struct vio_dring_state *dr; + + viodbg(HS, "GOT DRING_REG ACK ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + dr = &vio->drings[VIO_DRIVER_TX_RING]; + + if (!(vio->dr_state & VIO_DR_STATE_TXREQ)) + return handshake_failure(vio); + + dr->ident = pkt->dring_ident; + vio->dr_state |= VIO_DR_STATE_TXREG; + + if (all_drings_registered(vio)) { + if (send_rdx(vio) < 0) + return handshake_failure(vio); + vio->hs_state = VIO_HS_SENT_RDX; + } + return 0; +} + +static int process_dreg_nack(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + viodbg(HS, "GOT DRING_REG NACK ident[%llx] " + "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", + (unsigned long long) pkt->dring_ident, + pkt->num_descr, pkt->descr_size, pkt->options, + pkt->num_cookies); + + return handshake_failure(vio); +} + +static int process_dreg(struct vio_driver_state *vio, + struct vio_dring_register *pkt) +{ + if (!(vio->hs_state & VIO_HS_GOTVERS)) + return handshake_failure(vio); + + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_dreg_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_dreg_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_dreg_nack(vio, pkt); + + default: + return handshake_failure(vio); + } +} + +static int process_dunreg(struct vio_driver_state *vio, + struct vio_dring_unregister *pkt) +{ + struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_RX_RING]; + + viodbg(HS, "GOT DRING_UNREG\n"); + + if (pkt->dring_ident != dr->ident) + return 0; + + vio->dr_state &= ~VIO_DR_STATE_RXREG; + + memset(dr, 0, sizeof(*dr)); + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; + + return 0; +} + +static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX INFO\n"); + + pkt->tag.stype = VIO_SUBTYPE_ACK; + viodbg(HS, "SEND RDX ACK\n"); + if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_SENT_RDX_ACK; + return 0; +} + +static int process_rdx_ack(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX ACK\n"); + + if (!(vio->hs_state & VIO_HS_SENT_RDX)) + return handshake_failure(vio); + + vio->hs_state |= VIO_HS_GOT_RDX_ACK; + return 0; +} + +static int process_rdx_nack(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + viodbg(HS, "GOT RDX NACK\n"); + + return handshake_failure(vio); +} + +static int process_rdx(struct vio_driver_state *vio, struct vio_rdx *pkt) +{ + if (!all_drings_registered(vio)) + handshake_failure(vio); + + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return process_rdx_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return process_rdx_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return process_rdx_nack(vio, pkt); + + default: + return handshake_failure(vio); + } +} + +int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt) +{ + struct vio_msg_tag *tag = pkt; + u8 prev_state = vio->hs_state; + int err; + + switch (tag->stype_env) { + case VIO_VER_INFO: + err = process_ver(vio, pkt); + break; + + case VIO_ATTR_INFO: + err = process_attr(vio, pkt); + break; + + case VIO_DRING_REG: + err = process_dreg(vio, pkt); + break; + + case VIO_DRING_UNREG: + err = process_dunreg(vio, pkt); + break; + + case VIO_RDX: + err = process_rdx(vio, pkt); + break; + + default: + err = process_unknown(vio, pkt); + break; + } + if (!err && + vio->hs_state != prev_state && + (vio->hs_state & VIO_HS_COMPLETE)) + vio->ops->handshake_complete(vio); + + return err; +} +EXPORT_SYMBOL(vio_control_pkt_engine); + +void vio_conn_reset(struct vio_driver_state *vio) +{ +} +EXPORT_SYMBOL(vio_conn_reset); + +/* The issue is that the Solaris virtual disk server just mirrors the + * SID values it gets from the client peer. So we work around that + * here in vio_{validate,send}_sid() so that the drivers don't need + * to be aware of this crap. + */ +int vio_validate_sid(struct vio_driver_state *vio, struct vio_msg_tag *tp) +{ + u32 sid; + + /* Always let VERSION+INFO packets through unchecked, they + * define the new SID. + */ + if (tp->type == VIO_TYPE_CTRL && + tp->stype == VIO_SUBTYPE_INFO && + tp->stype_env == VIO_VER_INFO) + return 0; + + /* Ok, now figure out which SID to use. */ + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK_SERVER: + default: + sid = vio->_peer_sid; + break; + + case VDEV_DISK: + sid = vio->_local_sid; + break; + } + + if (sid == tp->sid) + return 0; + viodbg(DATA, "BAD SID tag->sid[%08x] peer_sid[%08x] local_sid[%08x]\n", + tp->sid, vio->_peer_sid, vio->_local_sid); + return -EINVAL; +} +EXPORT_SYMBOL(vio_validate_sid); + +u32 vio_send_sid(struct vio_driver_state *vio) +{ + switch (vio->dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK: + default: + return vio->_local_sid; + + case VDEV_DISK_SERVER: + return vio->_peer_sid; + } +} +EXPORT_SYMBOL(vio_send_sid); + +int vio_ldc_alloc(struct vio_driver_state *vio, + struct ldc_channel_config *base_cfg, + void *event_arg) +{ + struct ldc_channel_config cfg = *base_cfg; + struct ldc_channel *lp; + + cfg.tx_irq = vio->vdev->tx_irq; + cfg.rx_irq = vio->vdev->rx_irq; + + lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg); + if (IS_ERR(lp)) + return PTR_ERR(lp); + + vio->lp = lp; + + return 0; +} +EXPORT_SYMBOL(vio_ldc_alloc); + +void vio_ldc_free(struct vio_driver_state *vio) +{ + ldc_free(vio->lp); + vio->lp = NULL; + + kfree(vio->desc_buf); + vio->desc_buf = NULL; + vio->desc_buf_len = 0; +} +EXPORT_SYMBOL(vio_ldc_free); + +void vio_port_up(struct vio_driver_state *vio) +{ + unsigned long flags; + int err, state; + + spin_lock_irqsave(&vio->lock, flags); + + state = ldc_state(vio->lp); + + err = 0; + if (state == LDC_STATE_INIT) { + err = ldc_bind(vio->lp, vio->name); + if (err) + printk(KERN_WARNING "%s: Port %lu bind failed, " + "err=%d\n", + vio->name, vio->vdev->channel_id, err); + } + + if (!err) { + err = ldc_connect(vio->lp); + if (err) + printk(KERN_WARNING "%s: Port %lu connect failed, " + "err=%d\n", + vio->name, vio->vdev->channel_id, err); + } + if (err) { + unsigned long expires = jiffies + HZ; + + expires = round_jiffies(expires); + mod_timer(&vio->timer, expires); + } + + spin_unlock_irqrestore(&vio->lock, flags); +} +EXPORT_SYMBOL(vio_port_up); + +static void vio_port_timer(unsigned long _arg) +{ + struct vio_driver_state *vio = (struct vio_driver_state *) _arg; + + vio_port_up(vio); +} + +int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, + u8 dev_class, struct vio_version *ver_table, + int ver_table_size, struct vio_driver_ops *ops, + char *name) +{ + switch (dev_class) { + case VDEV_NETWORK: + case VDEV_NETWORK_SWITCH: + case VDEV_DISK: + case VDEV_DISK_SERVER: + break; + + default: + return -EINVAL; + } + + if (!ops->send_attr || + !ops->handle_attr || + !ops->handshake_complete) + return -EINVAL; + + if (!ver_table || ver_table_size < 0) + return -EINVAL; + + if (!name) + return -EINVAL; + + spin_lock_init(&vio->lock); + + vio->name = name; + + vio->dev_class = dev_class; + vio->vdev = vdev; + + vio->ver_table = ver_table; + vio->ver_table_entries = ver_table_size; + + vio->ops = ops; + + setup_timer(&vio->timer, vio_port_timer, (unsigned long) vio); + + return 0; +} +EXPORT_SYMBOL(vio_driver_init); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/ds.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/ds.c @@ -0,0 +1,1248 @@ +/* ds.c: Domain Services driver for Logical Domains + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define DRV_MODULE_NAME "ds" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Jul 11, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("Sun LDOM domain services driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +struct ds_msg_tag { + __u32 type; +#define DS_INIT_REQ 0x00 +#define DS_INIT_ACK 0x01 +#define DS_INIT_NACK 0x02 +#define DS_REG_REQ 0x03 +#define DS_REG_ACK 0x04 +#define DS_REG_NACK 0x05 +#define DS_UNREG_REQ 0x06 +#define DS_UNREG_ACK 0x07 +#define DS_UNREG_NACK 0x08 +#define DS_DATA 0x09 +#define DS_NACK 0x0a + + __u32 len; +}; + +/* Result codes */ +#define DS_OK 0x00 +#define DS_REG_VER_NACK 0x01 +#define DS_REG_DUP 0x02 +#define DS_INV_HDL 0x03 +#define DS_TYPE_UNKNOWN 0x04 + +struct ds_version { + __u16 major; + __u16 minor; +}; + +struct ds_ver_req { + struct ds_msg_tag tag; + struct ds_version ver; +}; + +struct ds_ver_ack { + struct ds_msg_tag tag; + __u16 minor; +}; + +struct ds_ver_nack { + struct ds_msg_tag tag; + __u16 major; +}; + +struct ds_reg_req { + struct ds_msg_tag tag; + __u64 handle; + __u16 major; + __u16 minor; + char svc_id[0]; +}; + +struct ds_reg_ack { + struct ds_msg_tag tag; + __u64 handle; + __u16 minor; +}; + +struct ds_reg_nack { + struct ds_msg_tag tag; + __u64 handle; + __u16 major; +}; + +struct ds_unreg_req { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_unreg_ack { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_unreg_nack { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_data { + struct ds_msg_tag tag; + __u64 handle; +}; + +struct ds_data_nack { + struct ds_msg_tag tag; + __u64 handle; + __u64 result; +}; + +struct ds_info; +struct ds_cap_state { + __u64 handle; + + void (*data)(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); + + const char *service_id; + + u8 state; +#define CAP_STATE_UNKNOWN 0x00 +#define CAP_STATE_REG_SENT 0x01 +#define CAP_STATE_REGISTERED 0x02 +}; + +static void md_update_data(struct ds_info *dp, struct ds_cap_state *cp, + void *buf, int len); +static void domain_shutdown_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); +static void domain_panic_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); +#ifdef CONFIG_HOTPLUG_CPU +static void dr_cpu_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); +#endif +static void ds_pri_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); +static void ds_var_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len); + +struct ds_cap_state ds_states_template[] = { + { + .service_id = "md-update", + .data = md_update_data, + }, + { + .service_id = "domain-shutdown", + .data = domain_shutdown_data, + }, + { + .service_id = "domain-panic", + .data = domain_panic_data, + }, +#ifdef CONFIG_HOTPLUG_CPU + { + .service_id = "dr-cpu", + .data = dr_cpu_data, + }, +#endif + { + .service_id = "pri", + .data = ds_pri_data, + }, + { + .service_id = "var-config", + .data = ds_var_data, + }, + { + .service_id = "var-config-backup", + .data = ds_var_data, + }, +}; + +static DEFINE_SPINLOCK(ds_lock); + +struct ds_info { + struct ldc_channel *lp; + u8 hs_state; +#define DS_HS_START 0x01 +#define DS_HS_DONE 0x02 + + u64 id; + + void *rcv_buf; + int rcv_buf_len; + + struct ds_cap_state *ds_states; + int num_ds_states; + + struct ds_info *next; +}; + +static struct ds_info *ds_info_list; + +static struct ds_cap_state *find_cap(struct ds_info *dp, u64 handle) +{ + unsigned int index = handle >> 32; + + if (index >= dp->num_ds_states) + return NULL; + return &dp->ds_states[index]; +} + +static struct ds_cap_state *find_cap_by_string(struct ds_info *dp, + const char *name) +{ + int i; + + for (i = 0; i < dp->num_ds_states; i++) { + if (strcmp(dp->ds_states[i].service_id, name)) + continue; + + return &dp->ds_states[i]; + } + return NULL; +} + +static int __ds_send(struct ldc_channel *lp, void *data, int len) +{ + int err, limit = 1000; + + err = -EINVAL; + while (limit-- > 0) { + err = ldc_write(lp, data, len); + if (!err || (err != -EAGAIN)) + break; + udelay(1); + } + + return err; +} + +static int ds_send(struct ldc_channel *lp, void *data, int len) +{ + unsigned long flags; + int err; + + spin_lock_irqsave(&ds_lock, flags); + err = __ds_send(lp, data, len); + spin_unlock_irqrestore(&ds_lock, flags); + + return err; +} + +struct ds_md_update_req { + __u64 req_num; +}; + +struct ds_md_update_res { + __u64 req_num; + __u32 result; +}; + +static void md_update_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ldc_channel *lp = dp->lp; + struct ds_data *dpkt = buf; + struct ds_md_update_req *rp; + struct { + struct ds_data data; + struct ds_md_update_res res; + } pkt; + + rp = (struct ds_md_update_req *) (dpkt + 1); + + printk(KERN_INFO "ds-%lu: Machine description update.\n", dp->id); + + mdesc_update(); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = cp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + + ds_send(lp, &pkt, sizeof(pkt)); +} + +struct ds_shutdown_req { + __u64 req_num; + __u32 ms_delay; +}; + +struct ds_shutdown_res { + __u64 req_num; + __u32 result; + char reason[1]; +}; + +static void domain_shutdown_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ldc_channel *lp = dp->lp; + struct ds_data *dpkt = buf; + struct ds_shutdown_req *rp; + struct { + struct ds_data data; + struct ds_shutdown_res res; + } pkt; + + rp = (struct ds_shutdown_req *) (dpkt + 1); + + printk(KERN_ALERT "ds-%lu: Shutdown request from " + "LDOM manager received.\n", dp->id); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = cp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + pkt.res.reason[0] = 0; + + ds_send(lp, &pkt, sizeof(pkt)); + + wake_up_powerd(); +} + +struct ds_panic_req { + __u64 req_num; +}; + +struct ds_panic_res { + __u64 req_num; + __u32 result; + char reason[1]; +}; + +static void domain_panic_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ldc_channel *lp = dp->lp; + struct ds_data *dpkt = buf; + struct ds_panic_req *rp; + struct { + struct ds_data data; + struct ds_panic_res res; + } pkt; + + rp = (struct ds_panic_req *) (dpkt + 1); + + printk(KERN_ALERT "ds-%lu: Panic request from " + "LDOM manager received.\n", dp->id); + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); + pkt.data.handle = cp->handle; + pkt.res.req_num = rp->req_num; + pkt.res.result = DS_OK; + pkt.res.reason[0] = 0; + + ds_send(lp, &pkt, sizeof(pkt)); + + panic("PANIC requested by LDOM manager."); +} + +#ifdef CONFIG_HOTPLUG_CPU +struct dr_cpu_tag { + __u64 req_num; + __u32 type; +#define DR_CPU_CONFIGURE 0x43 +#define DR_CPU_UNCONFIGURE 0x55 +#define DR_CPU_FORCE_UNCONFIGURE 0x46 +#define DR_CPU_STATUS 0x53 + +/* Responses */ +#define DR_CPU_OK 0x6f +#define DR_CPU_ERROR 0x65 + + __u32 num_records; +}; + +struct dr_cpu_resp_entry { + __u32 cpu; + __u32 result; +#define DR_CPU_RES_OK 0x00 +#define DR_CPU_RES_FAILURE 0x01 +#define DR_CPU_RES_BLOCKED 0x02 +#define DR_CPU_RES_CPU_NOT_RESPONDING 0x03 +#define DR_CPU_RES_NOT_IN_MD 0x04 + + __u32 stat; +#define DR_CPU_STAT_NOT_PRESENT 0x00 +#define DR_CPU_STAT_UNCONFIGURED 0x01 +#define DR_CPU_STAT_CONFIGURED 0x02 + + __u32 str_off; +}; + +static void __dr_cpu_send_error(struct ds_info *dp, + struct ds_cap_state *cp, + struct ds_data *data) +{ + struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); + struct { + struct ds_data data; + struct dr_cpu_tag tag; + } pkt; + int msg_len; + + memset(&pkt, 0, sizeof(pkt)); + pkt.data.tag.type = DS_DATA; + pkt.data.handle = cp->handle; + pkt.tag.req_num = tag->req_num; + pkt.tag.type = DR_CPU_ERROR; + pkt.tag.num_records = 0; + + msg_len = (sizeof(struct ds_data) + + sizeof(struct dr_cpu_tag)); + + pkt.data.tag.len = msg_len - sizeof(struct ds_msg_tag); + + __ds_send(dp->lp, &pkt, msg_len); +} + +static void dr_cpu_send_error(struct ds_info *dp, + struct ds_cap_state *cp, + struct ds_data *data) +{ + unsigned long flags; + + spin_lock_irqsave(&ds_lock, flags); + __dr_cpu_send_error(dp, cp, data); + spin_unlock_irqrestore(&ds_lock, flags); +} + +#define CPU_SENTINEL 0xffffffff + +static void purge_dups(u32 *list, u32 num_ents) +{ + unsigned int i; + + for (i = 0; i < num_ents; i++) { + u32 cpu = list[i]; + unsigned int j; + + if (cpu == CPU_SENTINEL) + continue; + + for (j = i + 1; j < num_ents; j++) { + if (list[j] == cpu) + list[j] = CPU_SENTINEL; + } + } +} + +static int dr_cpu_size_response(int ncpus) +{ + return (sizeof(struct ds_data) + + sizeof(struct dr_cpu_tag) + + (sizeof(struct dr_cpu_resp_entry) * ncpus)); +} + +static void dr_cpu_init_response(struct ds_data *resp, u64 req_num, + u64 handle, int resp_len, int ncpus, + cpumask_t *mask, u32 default_stat) +{ + struct dr_cpu_resp_entry *ent; + struct dr_cpu_tag *tag; + int i, cpu; + + tag = (struct dr_cpu_tag *) (resp + 1); + ent = (struct dr_cpu_resp_entry *) (tag + 1); + + resp->tag.type = DS_DATA; + resp->tag.len = resp_len - sizeof(struct ds_msg_tag); + resp->handle = handle; + tag->req_num = req_num; + tag->type = DR_CPU_OK; + tag->num_records = ncpus; + + i = 0; + for_each_cpu_mask(cpu, *mask) { + ent[i].cpu = cpu; + ent[i].result = DR_CPU_RES_OK; + ent[i].stat = default_stat; + i++; + } + BUG_ON(i != ncpus); +} + +static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, + u32 res, u32 stat) +{ + struct dr_cpu_resp_entry *ent; + struct dr_cpu_tag *tag; + int i; + + tag = (struct dr_cpu_tag *) (resp + 1); + ent = (struct dr_cpu_resp_entry *) (tag + 1); + + for (i = 0; i < ncpus; i++) { + if (ent[i].cpu != cpu) + continue; + ent[i].result = res; + ent[i].stat = stat; + break; + } +} + +static int dr_cpu_configure(struct ds_info *dp, + struct ds_cap_state *cp, + u64 req_num, + cpumask_t *mask) +{ + struct ds_data *resp; + int resp_len, ncpus, cpu; + unsigned long flags; + + ncpus = cpus_weight(*mask); + resp_len = dr_cpu_size_response(ncpus); + resp = kzalloc(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + dr_cpu_init_response(resp, req_num, cp->handle, + resp_len, ncpus, mask, + DR_CPU_STAT_CONFIGURED); + + mdesc_fill_in_cpu_data(*mask); + + for_each_cpu_mask(cpu, *mask) { + int err; + + printk(KERN_INFO "ds-%lu: Starting cpu %d...\n", + dp->id, cpu); + err = cpu_up(cpu); + if (err) { + __u32 res = DR_CPU_RES_FAILURE; + __u32 stat = DR_CPU_STAT_UNCONFIGURED; + + if (!cpu_present(cpu)) { + /* CPU not present in MD */ + res = DR_CPU_RES_NOT_IN_MD; + stat = DR_CPU_STAT_NOT_PRESENT; + } else if (err == -ENODEV) { + /* CPU did not call in successfully */ + res = DR_CPU_RES_CPU_NOT_RESPONDING; + } + + printk(KERN_INFO "ds-%lu: CPU startup failed err=%d\n", + dp->id, err); + dr_cpu_mark(resp, cpu, ncpus, res, stat); + } + } + + spin_lock_irqsave(&ds_lock, flags); + __ds_send(dp->lp, resp, resp_len); + spin_unlock_irqrestore(&ds_lock, flags); + + kfree(resp); + + /* Redistribute IRQs, taking into account the new cpus. */ + fixup_irqs(); + + return 0; +} + +static int dr_cpu_unconfigure(struct ds_info *dp, + struct ds_cap_state *cp, + u64 req_num, + cpumask_t *mask) +{ + struct ds_data *resp; + int resp_len, ncpus, cpu; + unsigned long flags; + + ncpus = cpus_weight(*mask); + resp_len = dr_cpu_size_response(ncpus); + resp = kzalloc(resp_len, GFP_KERNEL); + if (!resp) + return -ENOMEM; + + dr_cpu_init_response(resp, req_num, cp->handle, + resp_len, ncpus, mask, + DR_CPU_STAT_UNCONFIGURED); + + for_each_cpu_mask(cpu, *mask) { + int err; + + printk(KERN_INFO "ds-%lu: Shutting down cpu %d...\n", + dp->id, cpu); + err = cpu_down(cpu); + if (err) + dr_cpu_mark(resp, cpu, ncpus, + DR_CPU_RES_FAILURE, + DR_CPU_STAT_CONFIGURED); + } + + spin_lock_irqsave(&ds_lock, flags); + __ds_send(dp->lp, resp, resp_len); + spin_unlock_irqrestore(&ds_lock, flags); + + kfree(resp); + + return 0; +} + +static void dr_cpu_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ds_data *data = buf; + struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); + u32 *cpu_list = (u32 *) (tag + 1); + u64 req_num = tag->req_num; + cpumask_t mask; + unsigned int i; + int err; + + switch (tag->type) { + case DR_CPU_CONFIGURE: + case DR_CPU_UNCONFIGURE: + case DR_CPU_FORCE_UNCONFIGURE: + break; + + default: + dr_cpu_send_error(dp, cp, data); + return; + } + + purge_dups(cpu_list, tag->num_records); + + cpus_clear(mask); + for (i = 0; i < tag->num_records; i++) { + if (cpu_list[i] == CPU_SENTINEL) + continue; + + if (cpu_list[i] < NR_CPUS) + cpu_set(cpu_list[i], mask); + } + + if (tag->type == DR_CPU_CONFIGURE) + err = dr_cpu_configure(dp, cp, req_num, &mask); + else + err = dr_cpu_unconfigure(dp, cp, req_num, &mask); + + if (err) + dr_cpu_send_error(dp, cp, data); +} +#endif /* CONFIG_HOTPLUG_CPU */ + +struct ds_pri_msg { + __u64 req_num; + __u64 type; +#define DS_PRI_REQUEST 0x00 +#define DS_PRI_DATA 0x01 +#define DS_PRI_UPDATE 0x02 +}; + +static void ds_pri_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_pri_msg *rp; + + rp = (struct ds_pri_msg *) (dpkt + 1); + + printk(KERN_INFO "ds-%lu: PRI REQ [%lx:%lx], len=%d\n", + dp->id, rp->req_num, rp->type, len); +} + +struct ds_var_hdr { + __u32 type; +#define DS_VAR_SET_REQ 0x00 +#define DS_VAR_DELETE_REQ 0x01 +#define DS_VAR_SET_RESP 0x02 +#define DS_VAR_DELETE_RESP 0x03 +}; + +struct ds_var_set_msg { + struct ds_var_hdr hdr; + char name_and_value[0]; +}; + +struct ds_var_delete_msg { + struct ds_var_hdr hdr; + char name[0]; +}; + +struct ds_var_resp { + struct ds_var_hdr hdr; + __u32 result; +#define DS_VAR_SUCCESS 0x00 +#define DS_VAR_NO_SPACE 0x01 +#define DS_VAR_INVALID_VAR 0x02 +#define DS_VAR_INVALID_VAL 0x03 +#define DS_VAR_NOT_PRESENT 0x04 +}; + +static DEFINE_MUTEX(ds_var_mutex); +static int ds_var_doorbell; +static int ds_var_response; + +static void ds_var_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) +{ + struct ds_data *dpkt = buf; + struct ds_var_resp *rp; + + rp = (struct ds_var_resp *) (dpkt + 1); + + if (rp->hdr.type != DS_VAR_SET_RESP && + rp->hdr.type != DS_VAR_DELETE_RESP) + return; + + ds_var_response = rp->result; + wmb(); + ds_var_doorbell = 1; +} + +void ldom_set_var(const char *var, const char *value) +{ + struct ds_cap_state *cp; + struct ds_info *dp; + unsigned long flags; + + spin_lock_irqsave(&ds_lock, flags); + cp = NULL; + for (dp = ds_info_list; dp; dp = dp->next) { + struct ds_cap_state *tmp; + + tmp = find_cap_by_string(dp, "var-config"); + if (tmp && tmp->state == CAP_STATE_REGISTERED) { + cp = tmp; + break; + } + } + if (!cp) { + for (dp = ds_info_list; dp; dp = dp->next) { + struct ds_cap_state *tmp; + + tmp = find_cap_by_string(dp, "var-config-backup"); + if (tmp && tmp->state == CAP_STATE_REGISTERED) { + cp = tmp; + break; + } + } + } + spin_unlock_irqrestore(&ds_lock, flags); + + if (cp) { + union { + struct { + struct ds_data data; + struct ds_var_set_msg msg; + } header; + char all[512]; + } pkt; + char *base, *p; + int msg_len, loops; + + memset(&pkt, 0, sizeof(pkt)); + pkt.header.data.tag.type = DS_DATA; + pkt.header.data.handle = cp->handle; + pkt.header.msg.hdr.type = DS_VAR_SET_REQ; + base = p = &pkt.header.msg.name_and_value[0]; + strcpy(p, var); + p += strlen(var) + 1; + strcpy(p, value); + p += strlen(value) + 1; + + msg_len = (sizeof(struct ds_data) + + sizeof(struct ds_var_set_msg) + + (p - base)); + msg_len = (msg_len + 3) & ~3; + pkt.header.data.tag.len = msg_len - sizeof(struct ds_msg_tag); + + mutex_lock(&ds_var_mutex); + + spin_lock_irqsave(&ds_lock, flags); + ds_var_doorbell = 0; + ds_var_response = -1; + + __ds_send(dp->lp, &pkt, msg_len); + spin_unlock_irqrestore(&ds_lock, flags); + + loops = 1000; + while (ds_var_doorbell == 0) { + if (loops-- < 0) + break; + barrier(); + udelay(100); + } + + mutex_unlock(&ds_var_mutex); + + if (ds_var_doorbell == 0 || + ds_var_response != DS_VAR_SUCCESS) + printk(KERN_ERR "ds-%lu: var-config [%s:%s] " + "failed, response(%d).\n", + dp->id, var, value, + ds_var_response); + } else { + printk(KERN_ERR PFX "var-config not registered so " + "could not set (%s) variable to (%s).\n", + var, value); + } +} + +void ldom_reboot(const char *boot_command) +{ + /* Don't bother with any of this if the boot_command + * is empty. + */ + if (boot_command && strlen(boot_command)) { + char full_boot_str[256]; + + strcpy(full_boot_str, "boot "); + strcpy(full_boot_str + strlen("boot "), boot_command); + + ldom_set_var("reboot-command", full_boot_str); + } + sun4v_mach_sir(); +} + +void ldom_power_off(void) +{ + sun4v_mach_exit(0); +} + +static void ds_conn_reset(struct ds_info *dp) +{ + printk(KERN_ERR "ds-%lu: ds_conn_reset() from %p\n", + dp->id, __builtin_return_address(0)); +} + +static int register_services(struct ds_info *dp) +{ + struct ldc_channel *lp = dp->lp; + int i; + + for (i = 0; i < dp->num_ds_states; i++) { + struct { + struct ds_reg_req req; + u8 id_buf[256]; + } pbuf; + struct ds_cap_state *cp = &dp->ds_states[i]; + int err, msg_len; + u64 new_count; + + if (cp->state == CAP_STATE_REGISTERED) + continue; + + new_count = sched_clock() & 0xffffffff; + cp->handle = ((u64) i << 32) | new_count; + + msg_len = (sizeof(struct ds_reg_req) + + strlen(cp->service_id)); + + memset(&pbuf, 0, sizeof(pbuf)); + pbuf.req.tag.type = DS_REG_REQ; + pbuf.req.tag.len = (msg_len - sizeof(struct ds_msg_tag)); + pbuf.req.handle = cp->handle; + pbuf.req.major = 1; + pbuf.req.minor = 0; + strcpy(pbuf.req.svc_id, cp->service_id); + + err = __ds_send(lp, &pbuf, msg_len); + if (err > 0) + cp->state = CAP_STATE_REG_SENT; + } + return 0; +} + +static int ds_handshake(struct ds_info *dp, struct ds_msg_tag *pkt) +{ + + if (dp->hs_state == DS_HS_START) { + if (pkt->type != DS_INIT_ACK) + goto conn_reset; + + dp->hs_state = DS_HS_DONE; + + return register_services(dp); + } + + if (dp->hs_state != DS_HS_DONE) + goto conn_reset; + + if (pkt->type == DS_REG_ACK) { + struct ds_reg_ack *ap = (struct ds_reg_ack *) pkt; + struct ds_cap_state *cp = find_cap(dp, ap->handle); + + if (!cp) { + printk(KERN_ERR "ds-%lu: REG ACK for unknown " + "handle %lx\n", dp->id, ap->handle); + return 0; + } + printk(KERN_INFO "ds-%lu: Registered %s service.\n", + dp->id, cp->service_id); + cp->state = CAP_STATE_REGISTERED; + } else if (pkt->type == DS_REG_NACK) { + struct ds_reg_nack *np = (struct ds_reg_nack *) pkt; + struct ds_cap_state *cp = find_cap(dp, np->handle); + + if (!cp) { + printk(KERN_ERR "ds-%lu: REG NACK for " + "unknown handle %lx\n", + dp->id, np->handle); + return 0; + } + cp->state = CAP_STATE_UNKNOWN; + } + + return 0; + +conn_reset: + ds_conn_reset(dp); + return -ECONNRESET; +} + +static void __send_ds_nack(struct ds_info *dp, u64 handle) +{ + struct ds_data_nack nack = { + .tag = { + .type = DS_NACK, + .len = (sizeof(struct ds_data_nack) - + sizeof(struct ds_msg_tag)), + }, + .handle = handle, + .result = DS_INV_HDL, + }; + + __ds_send(dp->lp, &nack, sizeof(nack)); +} + +static LIST_HEAD(ds_work_list); +static DECLARE_WAIT_QUEUE_HEAD(ds_wait); + +struct ds_queue_entry { + struct list_head list; + struct ds_info *dp; + int req_len; + int __pad; + u64 req[0]; +}; + +static void process_ds_work(void) +{ + struct ds_queue_entry *qp, *tmp; + unsigned long flags; + LIST_HEAD(todo); + + spin_lock_irqsave(&ds_lock, flags); + list_splice(&ds_work_list, &todo); + INIT_LIST_HEAD(&ds_work_list); + spin_unlock_irqrestore(&ds_lock, flags); + + list_for_each_entry_safe(qp, tmp, &todo, list) { + struct ds_data *dpkt = (struct ds_data *) qp->req; + struct ds_info *dp = qp->dp; + struct ds_cap_state *cp = find_cap(dp, dpkt->handle); + int req_len = qp->req_len; + + if (!cp) { + printk(KERN_ERR "ds-%lu: Data for unknown " + "handle %lu\n", + dp->id, dpkt->handle); + + spin_lock_irqsave(&ds_lock, flags); + __send_ds_nack(dp, dpkt->handle); + spin_unlock_irqrestore(&ds_lock, flags); + } else { + cp->data(dp, cp, dpkt, req_len); + } + + list_del(&qp->list); + kfree(qp); + } +} + +static int ds_thread(void *__unused) +{ + DEFINE_WAIT(wait); + + while (1) { + prepare_to_wait(&ds_wait, &wait, TASK_INTERRUPTIBLE); + if (list_empty(&ds_work_list)) + schedule(); + finish_wait(&ds_wait, &wait); + + if (kthread_should_stop()) + break; + + process_ds_work(); + } + + return 0; +} + +static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len) +{ + struct ds_data *dpkt = (struct ds_data *) pkt; + struct ds_queue_entry *qp; + + qp = kmalloc(sizeof(struct ds_queue_entry) + len, GFP_ATOMIC); + if (!qp) { + __send_ds_nack(dp, dpkt->handle); + } else { + qp->dp = dp; + memcpy(&qp->req, pkt, len); + list_add_tail(&qp->list, &ds_work_list); + wake_up(&ds_wait); + } + return 0; +} + +static void ds_up(struct ds_info *dp) +{ + struct ldc_channel *lp = dp->lp; + struct ds_ver_req req; + int err; + + req.tag.type = DS_INIT_REQ; + req.tag.len = sizeof(req) - sizeof(struct ds_msg_tag); + req.ver.major = 1; + req.ver.minor = 0; + + err = __ds_send(lp, &req, sizeof(req)); + if (err > 0) + dp->hs_state = DS_HS_START; +} + +static void ds_reset(struct ds_info *dp) +{ + int i; + + dp->hs_state = 0; + + for (i = 0; i < dp->num_ds_states; i++) { + struct ds_cap_state *cp = &dp->ds_states[i]; + + cp->state = CAP_STATE_UNKNOWN; + } +} + +static void ds_event(void *arg, int event) +{ + struct ds_info *dp = arg; + struct ldc_channel *lp = dp->lp; + unsigned long flags; + int err; + + spin_lock_irqsave(&ds_lock, flags); + + if (event == LDC_EVENT_UP) { + ds_up(dp); + spin_unlock_irqrestore(&ds_lock, flags); + return; + } + + if (event == LDC_EVENT_RESET) { + ds_reset(dp); + spin_unlock_irqrestore(&ds_lock, flags); + return; + } + + if (event != LDC_EVENT_DATA_READY) { + printk(KERN_WARNING "ds-%lu: Unexpected LDC event %d\n", + dp->id, event); + spin_unlock_irqrestore(&ds_lock, flags); + return; + } + + err = 0; + while (1) { + struct ds_msg_tag *tag; + + err = ldc_read(lp, dp->rcv_buf, sizeof(*tag)); + + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + ds_conn_reset(dp); + break; + } + if (err == 0) + break; + + tag = dp->rcv_buf; + err = ldc_read(lp, tag + 1, tag->len); + + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + ds_conn_reset(dp); + break; + } + if (err < tag->len) + break; + + if (tag->type < DS_DATA) + err = ds_handshake(dp, dp->rcv_buf); + else + err = ds_data(dp, dp->rcv_buf, + sizeof(*tag) + err); + if (err == -ECONNRESET) + break; + } + + spin_unlock_irqrestore(&ds_lock, flags); +} + +static int __devinit ds_probe(struct vio_dev *vdev, + const struct vio_device_id *id) +{ + static int ds_version_printed; + struct ldc_channel_config ds_cfg = { + .event = ds_event, + .mtu = 4096, + .mode = LDC_MODE_STREAM, + }; + struct mdesc_handle *hp; + struct ldc_channel *lp; + struct ds_info *dp; + const u64 *val; + int err, i; + + if (ds_version_printed++ == 0) + printk(KERN_INFO "%s", version); + + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + err = -ENOMEM; + if (!dp) + goto out_err; + + hp = mdesc_grab(); + val = mdesc_get_property(hp, vdev->mp, "id", NULL); + if (val) + dp->id = *val; + mdesc_release(hp); + + dp->rcv_buf = kzalloc(4096, GFP_KERNEL); + if (!dp->rcv_buf) + goto out_free_dp; + + dp->rcv_buf_len = 4096; + + dp->ds_states = kzalloc(sizeof(ds_states_template), + GFP_KERNEL); + if (!dp->ds_states) + goto out_free_rcv_buf; + + memcpy(dp->ds_states, ds_states_template, + sizeof(ds_states_template)); + dp->num_ds_states = ARRAY_SIZE(ds_states_template); + + for (i = 0; i < dp->num_ds_states; i++) + dp->ds_states[i].handle = ((u64)i << 32); + + ds_cfg.tx_irq = vdev->tx_irq; + ds_cfg.rx_irq = vdev->rx_irq; + + lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out_free_ds_states; + } + dp->lp = lp; + + err = ldc_bind(lp, "DS"); + if (err) + goto out_free_ldc; + + spin_lock_irq(&ds_lock); + dp->next = ds_info_list; + ds_info_list = dp; + spin_unlock_irq(&ds_lock); + + start_powerd(); + + return err; + +out_free_ldc: + ldc_free(dp->lp); + +out_free_ds_states: + kfree(dp->ds_states); + +out_free_rcv_buf: + kfree(dp->rcv_buf); + +out_free_dp: + kfree(dp); + +out_err: + return err; +} + +static int ds_remove(struct vio_dev *vdev) +{ + return 0; +} + +static struct vio_device_id ds_match[] = { + { + .type = "domain-services-port", + }, + {}, +}; + +static struct vio_driver ds_driver = { + .id_table = ds_match, + .probe = ds_probe, + .remove = ds_remove, + .driver = { + .name = "ds", + .owner = THIS_MODULE, + } +}; + +static int __init ds_init(void) +{ + kthread_run(ds_thread, NULL, "kldomd"); + + return vio_register_driver(&ds_driver); +} + +subsys_initcall(ds_init); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/smp.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/smp.c @@ -1,6 +1,6 @@ /* smp.c: Sparc64 SMP support. * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -41,22 +43,26 @@ #include #include #include +#include +#include extern void calibrate_delay(void); int sparc64_multi_core __read_mostly; -/* Please don't make this stuff initdata!!! --DaveM */ -unsigned char boot_cpu_id; - +cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; -cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; cpumask_t cpu_core_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; + +EXPORT_SYMBOL(cpu_possible_map); +EXPORT_SYMBOL(cpu_online_map); +EXPORT_SYMBOL(cpu_sibling_map); +EXPORT_SYMBOL(cpu_core_map); + static cpumask_t smp_commenced_mask; -static cpumask_t cpu_callout_map; void smp_info(struct seq_file *m) { @@ -73,18 +79,17 @@ for_each_online_cpu(i) seq_printf(m, - "Cpu%dBogo\t: %lu.%02lu\n" "Cpu%dClkTck\t: %016lx\n", - i, cpu_data(i).udelay_val / (500000/HZ), - (cpu_data(i).udelay_val / (5000/HZ)) % 100, i, cpu_data(i).clock_tick); } +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); + extern void setup_sparc64_timer(void); static volatile unsigned long callin_flag = 0; -void __init smp_callin(void) +void __devinit smp_callin(void) { int cpuid = hard_smp_processor_id(); @@ -102,8 +107,6 @@ local_irq_enable(); - calibrate_delay(); - cpu_data(cpuid).udelay_val = loops_per_jiffy; callin_flag = 1; __asm__ __volatile__("membar #Sync\n\t" "flush %%g6" : : : "memory"); @@ -120,7 +123,9 @@ while (!cpu_isset(cpuid, smp_commenced_mask)) rmb(); + spin_lock(&call_lock); cpu_set(cpuid, cpu_online_map); + spin_unlock(&call_lock); /* idle thread is expected to have preempt disabled */ preempt_disable(); @@ -268,7 +273,66 @@ spin_unlock_irqrestore(&itc_sync_lock, flags); } -extern void sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load); +#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) +/* XXX Put this in some common place. XXX */ +static unsigned long kimage_addr_to_ra(void *p) +{ + unsigned long val = (unsigned long) p; + + return kern_base + (val - KERNBASE); +} + +static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg) +{ + extern unsigned long sparc64_ttable_tl0; + extern unsigned long kern_locked_tte_data; + extern int bigkernel; + struct hvtramp_descr *hdesc; + unsigned long trampoline_ra; + struct trap_per_cpu *tb; + u64 tte_vaddr, tte_data; + unsigned long hv_err; + + hdesc = kzalloc(sizeof(*hdesc), GFP_KERNEL); + if (!hdesc) { + printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate " + "hvtramp_descr.\n"); + return; + } + + hdesc->cpu = cpu; + hdesc->num_mappings = (bigkernel ? 2 : 1); + + tb = &trap_block[cpu]; + tb->hdesc = hdesc; + + hdesc->fault_info_va = (unsigned long) &tb->fault_info; + hdesc->fault_info_pa = kimage_addr_to_ra(&tb->fault_info); + + hdesc->thread_reg = thread_reg; + + tte_vaddr = (unsigned long) KERNBASE; + tte_data = kern_locked_tte_data; + + hdesc->maps[0].vaddr = tte_vaddr; + hdesc->maps[0].tte = tte_data; + if (bigkernel) { + tte_vaddr += 0x400000; + tte_data += 0x400000; + hdesc->maps[1].vaddr = tte_vaddr; + hdesc->maps[1].tte = tte_data; + } + + trampoline_ra = kimage_addr_to_ra(hv_cpu_startup); + + hv_err = sun4v_cpu_start(cpu, trampoline_ra, + kimage_addr_to_ra(&sparc64_ttable_tl0), + __pa(hdesc)); + if (hv_err) + printk(KERN_ERR "ldom_startcpu_cpuid: sun4v_cpu_start() " + "gives error %lu\n", hv_err); +} +#endif extern unsigned long sparc64_cpu_startup; @@ -280,6 +344,7 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) { + struct trap_per_cpu *tb = &trap_block[cpu]; unsigned long entry = (unsigned long)(&sparc64_cpu_startup); unsigned long cookie = @@ -288,22 +353,26 @@ int timeout, ret; p = fork_idle(cpu); + if (IS_ERR(p)) + return PTR_ERR(p); callin_flag = 0; cpu_new_thread = task_thread_info(p); - cpu_set(cpu, cpu_callout_map); if (tlb_type == hypervisor) { - /* Alloc the mondo queues, cpu will load them. */ - sun4v_init_mondo_queues(0, cpu, 1, 0); - - prom_startcpu_cpuid(cpu, entry, cookie); +#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) + if (ldom_domaining_enabled) + ldom_startcpu_cpuid(cpu, + (unsigned long) cpu_new_thread); + else +#endif + prom_startcpu_cpuid(cpu, entry, cookie); } else { struct device_node *dp = of_find_node_by_cpuid(cpu); prom_startcpu(dp->node, entry, cookie); } - for (timeout = 0; timeout < 5000000; timeout++) { + for (timeout = 0; timeout < 50000; timeout++) { if (callin_flag) break; udelay(100); @@ -313,11 +382,15 @@ ret = 0; } else { printk("Processor %d is stuck.\n", cpu); - cpu_clear(cpu, cpu_callout_map); ret = -ENODEV; } cpu_new_thread = NULL; + if (tb->hdesc) { + kfree(tb->hdesc); + tb->hdesc = NULL; + } + return ret; } @@ -403,7 +476,7 @@ */ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { - u64 pstate, ver; + u64 pstate, ver, busy_mask; int nack_busy_id, is_jbus, need_more; if (cpus_empty(mask)) @@ -435,14 +508,20 @@ "i" (ASI_INTR_W)); nack_busy_id = 0; + busy_mask = 0; { int i; for_each_cpu_mask(i, mask) { u64 target = (i << 14) | 0x70; - if (!is_jbus) + if (is_jbus) { + busy_mask |= (0x1UL << (i * 2)); + } else { target |= (nack_busy_id << 24); + busy_mask |= (0x1UL << + (nack_busy_id * 2)); + } __asm__ __volatile__( "stxa %%g0, [%0] %1\n\t" "membar #Sync\n\t" @@ -458,15 +537,16 @@ /* Now, poll for completion. */ { - u64 dispatch_stat; + u64 dispatch_stat, nack_mask; long stuck; stuck = 100000 * nack_busy_id; + nack_mask = busy_mask << 1; do { __asm__ __volatile__("ldxa [%%g0] %1, %0" : "=r" (dispatch_stat) : "i" (ASI_INTR_DISPATCH_STAT)); - if (dispatch_stat == 0UL) { + if (!(dispatch_stat & (busy_mask | nack_mask))) { __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); if (unlikely(need_more)) { @@ -483,12 +563,12 @@ } if (!--stuck) break; - } while (dispatch_stat & 0x5555555555555555UL); + } while (dispatch_stat & busy_mask); __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); - if ((dispatch_stat & ~(0x5555555555555555UL)) == 0) { + if (dispatch_stat & busy_mask) { /* Busy bits will not clear, continue instead * of freezing up on this cpu. */ @@ -720,7 +800,6 @@ int wait; }; -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); static struct call_data_struct *call_data; extern unsigned long xcall_call_function; @@ -1152,11 +1231,6 @@ preempt_enable(); } -void __init smp_tick_init(void) -{ - boot_cpu_id = hard_smp_processor_id(); -} - /* /proc/profile writes can call this, don't __init it please. */ int setup_profiling_timer(unsigned int multiplier) { @@ -1189,23 +1263,8 @@ smallest / 1024U / 1024U); } -/* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { - int i; - - if (num_possible_cpus() > max_cpus) { - for_each_possible_cpu(i) { - if (i != boot_cpu_id) { - cpu_clear(i, phys_cpu_present_map); - cpu_clear(i, cpu_present_map); - if (num_possible_cpus() <= max_cpus) - break; - } - } - } - - cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; smp_tune_scheduling(); } @@ -1217,30 +1276,32 @@ { unsigned int i; - for_each_possible_cpu(i) { + for_each_present_cpu(i) { unsigned int j; + cpus_clear(cpu_core_map[i]); if (cpu_data(i).core_id == 0) { cpu_set(i, cpu_core_map[i]); continue; } - for_each_possible_cpu(j) { + for_each_present_cpu(j) { if (cpu_data(i).core_id == cpu_data(j).core_id) cpu_set(j, cpu_core_map[i]); } } - for_each_possible_cpu(i) { + for_each_present_cpu(i) { unsigned int j; + cpus_clear(cpu_sibling_map[i]); if (cpu_data(i).proc_id == -1) { cpu_set(i, cpu_sibling_map[i]); continue; } - for_each_possible_cpu(j) { + for_each_present_cpu(j) { if (cpu_data(i).proc_id == cpu_data(j).proc_id) cpu_set(j, cpu_sibling_map[i]); @@ -1269,18 +1330,112 @@ return ret; } -void __init smp_cpus_done(unsigned int max_cpus) +#ifdef CONFIG_HOTPLUG_CPU +void cpu_play_dead(void) { - unsigned long bogosum = 0; + int cpu = smp_processor_id(); + unsigned long pstate; + + idle_task_exit(); + + if (tlb_type == hypervisor) { + struct trap_per_cpu *tb = &trap_block[cpu]; + + sun4v_cpu_qconf(HV_CPU_QUEUE_CPU_MONDO, + tb->cpu_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_DEVICE_MONDO, + tb->dev_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_RES_ERROR, + tb->resum_mondo_pa, 0); + sun4v_cpu_qconf(HV_CPU_QUEUE_NONRES_ERROR, + tb->nonresum_mondo_pa, 0); + } + + cpu_clear(cpu, smp_commenced_mask); + membar_safe("#Sync"); + + local_irq_disable(); + + __asm__ __volatile__( + "rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + while (1) + barrier(); +} + +int __cpu_disable(void) +{ + int cpu = smp_processor_id(); + cpuinfo_sparc *c; int i; - for_each_online_cpu(i) - bogosum += cpu_data(i).udelay_val; - printk("Total of %ld processors activated " - "(%lu.%02lu BogoMIPS).\n", - (long) num_online_cpus(), - bogosum/(500000/HZ), - (bogosum/(5000/HZ))%100); + for_each_cpu_mask(i, cpu_core_map[cpu]) + cpu_clear(cpu, cpu_core_map[i]); + cpus_clear(cpu_core_map[cpu]); + + for_each_cpu_mask(i, cpu_sibling_map[cpu]) + cpu_clear(cpu, cpu_sibling_map[i]); + cpus_clear(cpu_sibling_map[cpu]); + + c = &cpu_data(cpu); + + c->core_id = 0; + c->proc_id = -1; + + spin_lock(&call_lock); + cpu_clear(cpu, cpu_online_map); + spin_unlock(&call_lock); + + smp_wmb(); + + /* Make sure no interrupts point to this cpu. */ + fixup_irqs(); + + local_irq_enable(); + mdelay(1); + local_irq_disable(); + + return 0; +} + +void __cpu_die(unsigned int cpu) +{ + int i; + + for (i = 0; i < 100; i++) { + smp_rmb(); + if (!cpu_isset(cpu, smp_commenced_mask)) + break; + msleep(100); + } + if (cpu_isset(cpu, smp_commenced_mask)) { + printk(KERN_ERR "CPU %u didn't die...\n", cpu); + } else { +#if defined(CONFIG_SUN_LDOMS) + unsigned long hv_err; + int limit = 100; + + do { + hv_err = sun4v_cpu_stop(cpu); + if (hv_err == HV_EOK) { + cpu_clear(cpu, cpu_present_map); + break; + } + } while (--limit > 0); + if (limit <= 0) { + printk(KERN_ERR "sun4v_cpu_stop() fails err=%lu\n", + hv_err); + } +#endif + } +} +#endif + +void __init smp_cpus_done(unsigned int max_cpus) +{ } void smp_send_reschedule(int cpu) --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/vio.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/vio.c @@ -0,0 +1,453 @@ +/* vio.c: Virtual I/O channel devices probing infrastructure. + * + * Copyright (c) 2003-2005 IBM Corp. + * Dave Engebretsen engebret@us.ibm.com + * Santiago Leon santil@us.ibm.com + * Hollis Blanchard + * Stephen Rothwell + * + * Adapted to sparc64 by David S. Miller davem@davemloft.net + */ + +#include +#include +#include + +#include +#include + +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *matches, + const struct vio_dev *dev) +{ + const char *type, *compat; + int len; + + type = dev->type; + compat = dev->compat; + len = dev->compat_len; + + while (matches->type[0] || matches->compat[0]) { + int match = 1; + if (matches->type[0]) + match &= !strcmp(matches->type, type); + + if (matches->compat[0]) { + match &= len && + of_find_in_proplist(compat, matches->compat, len); + } + if (match) + return matches; + matches++; + } + return NULL; +} + +static int vio_bus_match(struct device *dev, struct device_driver *drv) +{ + struct vio_dev *vio_dev = to_vio_dev(dev); + struct vio_driver *vio_drv = to_vio_driver(drv); + const struct vio_device_id *matches = vio_drv->id_table; + + if (!matches) + return 0; + + return vio_match_device(matches, vio_dev) != NULL; +} + +static int vio_device_probe(struct device *dev) +{ + struct vio_dev *vdev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + const struct vio_device_id *id; + int error = -ENODEV; + + if (drv->probe) { + id = vio_match_device(drv->id_table, vdev); + if (id) + error = drv->probe(vdev, id); + } + + return error; +} + +static int vio_device_remove(struct device *dev) +{ + struct vio_dev *vdev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + + if (drv->remove) + return drv->remove(vdev); + + return 1; +} + +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vio_dev *vdev = to_vio_dev(dev); + const char *str = "none"; + + if (!strcmp(vdev->type, "vnet-port")) + str = "vnet"; + else if (!strcmp(vdev->type, "vdc-port")) + str = "vdisk"; + + return sprintf(buf, "%s\n", str); +} + +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vio_dev *vdev = to_vio_dev(dev); + return sprintf(buf, "%s\n", vdev->type); +} + +static struct device_attribute vio_dev_attrs[] = { + __ATTR_RO(devspec), + __ATTR_RO(type), + __ATTR_NULL +}; + +static struct bus_type vio_bus_type = { + .name = "vio", + .dev_attrs = vio_dev_attrs, + .match = vio_bus_match, + .probe = vio_device_probe, + .remove = vio_device_remove, +}; + +int vio_register_driver(struct vio_driver *viodrv) +{ + viodrv->driver.bus = &vio_bus_type; + + return driver_register(&viodrv->driver); +} +EXPORT_SYMBOL(vio_register_driver); + +void vio_unregister_driver(struct vio_driver *viodrv) +{ + driver_unregister(&viodrv->driver); +} +EXPORT_SYMBOL(vio_unregister_driver); + +static void __devinit vio_dev_release(struct device *dev) +{ + kfree(to_vio_dev(dev)); +} + +static ssize_t +show_pciobppath_attr(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vio_dev *vdev; + struct device_node *dp; + + vdev = to_vio_dev(dev); + dp = vdev->dp; + + return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); +} + +static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, + show_pciobppath_attr, NULL); + +struct device_node *cdev_node; + +static struct vio_dev *root_vdev; +static u64 cdev_cfg_handle; + +static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp, + struct vio_dev *vdev) +{ + u64 a; + + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + const u64 *chan_id; + const u64 *irq; + u64 target; + + target = mdesc_arc_target(hp, a); + + irq = mdesc_get_property(hp, target, "tx-ino", NULL); + if (irq) + vdev->tx_irq = sun4v_build_virq(cdev_cfg_handle, *irq); + + irq = mdesc_get_property(hp, target, "rx-ino", NULL); + if (irq) + vdev->rx_irq = sun4v_build_virq(cdev_cfg_handle, *irq); + + chan_id = mdesc_get_property(hp, target, "id", NULL); + if (chan_id) + vdev->channel_id = *chan_id; + } +} + +static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, + struct device *parent) +{ + const char *type, *compat, *bus_id_name; + struct device_node *dp; + struct vio_dev *vdev; + int err, tlen, clen; + const u64 *id, *cfg_handle; + u64 a; + + type = mdesc_get_property(hp, mp, "device-type", &tlen); + if (!type) { + type = mdesc_get_property(hp, mp, "name", &tlen); + if (!type) { + type = mdesc_node_name(hp, mp); + tlen = strlen(type) + 1; + } + } + if (tlen > VIO_MAX_TYPE_LEN) { + printk(KERN_ERR "VIO: Type string [%s] is too long.\n", + type); + return NULL; + } + + id = mdesc_get_property(hp, mp, "id", NULL); + + cfg_handle = NULL; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { + u64 target; + + target = mdesc_arc_target(hp, a); + cfg_handle = mdesc_get_property(hp, target, + "cfg-handle", NULL); + if (cfg_handle) + break; + } + + bus_id_name = type; + if (!strcmp(type, "domain-services-port")) + bus_id_name = "ds"; + + if (strlen(bus_id_name) >= KOBJ_NAME_LEN - 4) { + printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n", + bus_id_name); + return NULL; + } + + compat = mdesc_get_property(hp, mp, "device-type", &clen); + if (!compat) { + clen = 0; + } else if (clen > VIO_MAX_COMPAT_LEN) { + printk(KERN_ERR "VIO: Compat len %d for [%s] is too long.\n", + clen, type); + return NULL; + } + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + if (!vdev) { + printk(KERN_ERR "VIO: Could not allocate vio_dev\n"); + return NULL; + } + + vdev->mp = mp; + memcpy(vdev->type, type, tlen); + if (compat) + memcpy(vdev->compat, compat, clen); + else + memset(vdev->compat, 0, sizeof(vdev->compat)); + vdev->compat_len = clen; + + vdev->channel_id = ~0UL; + vdev->tx_irq = ~0; + vdev->rx_irq = ~0; + + vio_fill_channel_info(hp, mp, vdev); + + if (!id) { + snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", + bus_id_name); + vdev->dev_no = ~(u64)0; + } else if (!cfg_handle) { + snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", + bus_id_name, *id); + vdev->dev_no = *id; + } else { + snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu", + bus_id_name, *cfg_handle, *id); + vdev->dev_no = *cfg_handle; + } + + vdev->dev.parent = parent; + vdev->dev.bus = &vio_bus_type; + vdev->dev.release = vio_dev_release; + + if (parent == NULL) { + dp = cdev_node; + } else if (to_vio_dev(parent) == root_vdev) { + dp = of_get_next_child(cdev_node, NULL); + while (dp) { + if (!strcmp(dp->type, type)) + break; + + dp = of_get_next_child(cdev_node, dp); + } + } else { + dp = to_vio_dev(parent)->dp; + } + vdev->dp = dp; + + printk(KERN_INFO "VIO: Adding device %s\n", vdev->dev.bus_id); + + err = device_register(&vdev->dev); + if (err) { + printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", + vdev->dev.bus_id, err); + kfree(vdev); + return NULL; + } + if (vdev->dp) + err = sysfs_create_file(&vdev->dev.kobj, + &dev_attr_obppath.attr); + + return vdev; +} + +static void vio_add(struct mdesc_handle *hp, u64 node) +{ + (void) vio_create_one(hp, node, &root_vdev->dev); +} + +static int vio_md_node_match(struct device *dev, void *arg) +{ + struct vio_dev *vdev = to_vio_dev(dev); + + if (vdev->mp == (u64) arg) + return 1; + + return 0; +} + +static void vio_remove(struct mdesc_handle *hp, u64 node) +{ + struct device *dev; + + dev = device_find_child(&root_vdev->dev, (void *) node, + vio_md_node_match); + if (dev) { + printk(KERN_INFO "VIO: Removing device %s\n", dev->bus_id); + + device_unregister(dev); + } +} + +static struct mdesc_notifier_client vio_device_notifier = { + .add = vio_add, + .remove = vio_remove, + .node_name = "virtual-device-port", +}; + +/* We are only interested in domain service ports under the + * "domain-services" node. On control nodes there is another port + * under "openboot" that we should not mess with as aparently that is + * reserved exclusively for OBP use. + */ +static void vio_add_ds(struct mdesc_handle *hp, u64 node) +{ + int found; + u64 a; + + found = 0; + mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { + u64 target = mdesc_arc_target(hp, a); + const char *name = mdesc_node_name(hp, target); + + if (!strcmp(name, "domain-services")) { + found = 1; + break; + } + } + + if (found) + (void) vio_create_one(hp, node, &root_vdev->dev); +} + +static struct mdesc_notifier_client vio_ds_notifier = { + .add = vio_add_ds, + .remove = vio_remove, + .node_name = "domain-services-port", +}; + +const char *channel_devices_node = "channel-devices"; +const char *channel_devices_compat = "SUNW,sun4v-channel-devices"; +const char *cfg_handle_prop = "cfg-handle"; + +static int __init vio_init(void) +{ + struct mdesc_handle *hp; + const char *compat; + const u64 *cfg_handle; + int err, len; + u64 root; + + err = bus_register(&vio_bus_type); + if (err) { + printk(KERN_ERR "VIO: Could not register bus type err=%d\n", + err); + return err; + } + + hp = mdesc_grab(); + if (!hp) + return 0; + + root = mdesc_node_by_name(hp, MDESC_NODE_NULL, channel_devices_node); + if (root == MDESC_NODE_NULL) { + printk(KERN_INFO "VIO: No channel-devices MDESC node.\n"); + mdesc_release(hp); + return 0; + } + + cdev_node = of_find_node_by_name(NULL, "channel-devices"); + err = -ENODEV; + if (!cdev_node) { + printk(KERN_INFO "VIO: No channel-devices OBP node.\n"); + goto out_release; + } + + compat = mdesc_get_property(hp, root, "compatible", &len); + if (!compat) { + printk(KERN_ERR "VIO: Channel devices lacks compatible " + "property\n"); + goto out_release; + } + if (!of_find_in_proplist(compat, channel_devices_compat, len)) { + printk(KERN_ERR "VIO: Channel devices node lacks (%s) " + "compat entry.\n", channel_devices_compat); + goto out_release; + } + + cfg_handle = mdesc_get_property(hp, root, cfg_handle_prop, NULL); + if (!cfg_handle) { + printk(KERN_ERR "VIO: Channel devices lacks %s property\n", + cfg_handle_prop); + goto out_release; + } + + cdev_cfg_handle = *cfg_handle; + + root_vdev = vio_create_one(hp, root, NULL); + err = -ENODEV; + if (!root_vdev) { + printk(KERN_ERR "VIO: Coult not create root device.\n"); + goto out_release; + } + + mdesc_register_notifier(&vio_device_notifier); + mdesc_register_notifier(&vio_ds_notifier); + + mdesc_release(hp); + + return err; + +out_release: + mdesc_release(hp); + return err; +} + +postcore_initcall(vio_init); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/pci_fire.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/pci_fire.c @@ -6,9 +6,12 @@ #include #include #include +#include +#include #include #include +#include #include "pci_impl.h" @@ -80,6 +83,440 @@ fire_write(iommu->iommu_control, control); } +#ifdef CONFIG_PCI_MSI +struct pci_msiq_entry { + u64 word0; +#define MSIQ_WORD0_RESV 0x8000000000000000UL +#define MSIQ_WORD0_FMT_TYPE 0x7f00000000000000UL +#define MSIQ_WORD0_FMT_TYPE_SHIFT 56 +#define MSIQ_WORD0_LEN 0x00ffc00000000000UL +#define MSIQ_WORD0_LEN_SHIFT 46 +#define MSIQ_WORD0_ADDR0 0x00003fff00000000UL +#define MSIQ_WORD0_ADDR0_SHIFT 32 +#define MSIQ_WORD0_RID 0x00000000ffff0000UL +#define MSIQ_WORD0_RID_SHIFT 16 +#define MSIQ_WORD0_DATA0 0x000000000000ffffUL +#define MSIQ_WORD0_DATA0_SHIFT 0 + +#define MSIQ_TYPE_MSG 0x6 +#define MSIQ_TYPE_MSI32 0xb +#define MSIQ_TYPE_MSI64 0xf + + u64 word1; +#define MSIQ_WORD1_ADDR1 0xffffffffffff0000UL +#define MSIQ_WORD1_ADDR1_SHIFT 16 +#define MSIQ_WORD1_DATA1 0x000000000000ffffUL +#define MSIQ_WORD1_DATA1_SHIFT 0 + + u64 resv[6]; +}; + +/* All MSI registers are offset from pbm->pbm_regs */ +#define EVENT_QUEUE_BASE_ADDR_REG 0x010000UL +#define EVENT_QUEUE_BASE_ADDR_ALL_ONES 0xfffc000000000000UL + +#define EVENT_QUEUE_CONTROL_SET(EQ) (0x011000UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_CONTROL_SET_OFLOW 0x0200000000000000UL +#define EVENT_QUEUE_CONTROL_SET_EN 0x0000100000000000UL + +#define EVENT_QUEUE_CONTROL_CLEAR(EQ) (0x011200UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_CONTROL_CLEAR_OF 0x0200000000000000UL +#define EVENT_QUEUE_CONTROL_CLEAR_E2I 0x0000800000000000UL +#define EVENT_QUEUE_CONTROL_CLEAR_DIS 0x0000100000000000UL + +#define EVENT_QUEUE_STATE(EQ) (0x011400UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_STATE_MASK 0x0000000000000007UL +#define EVENT_QUEUE_STATE_IDLE 0x0000000000000001UL +#define EVENT_QUEUE_STATE_ACTIVE 0x0000000000000002UL +#define EVENT_QUEUE_STATE_ERROR 0x0000000000000004UL + +#define EVENT_QUEUE_TAIL(EQ) (0x011600UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_TAIL_OFLOW 0x0200000000000000UL +#define EVENT_QUEUE_TAIL_VAL 0x000000000000007fUL + +#define EVENT_QUEUE_HEAD(EQ) (0x011800UL + (EQ) * 0x8UL) +#define EVENT_QUEUE_HEAD_VAL 0x000000000000007fUL + +#define MSI_MAP(MSI) (0x020000UL + (MSI) * 0x8UL) +#define MSI_MAP_VALID 0x8000000000000000UL +#define MSI_MAP_EQWR_N 0x4000000000000000UL +#define MSI_MAP_EQNUM 0x000000000000003fUL + +#define MSI_CLEAR(MSI) (0x028000UL + (MSI) * 0x8UL) +#define MSI_CLEAR_EQWR_N 0x4000000000000000UL + +#define IMONDO_DATA0 0x02C000UL +#define IMONDO_DATA0_DATA 0xffffffffffffffc0UL + +#define IMONDO_DATA1 0x02C008UL +#define IMONDO_DATA1_DATA 0xffffffffffffffffUL + +#define MSI_32BIT_ADDR 0x034000UL +#define MSI_32BIT_ADDR_VAL 0x00000000ffff0000UL + +#define MSI_64BIT_ADDR 0x034008UL +#define MSI_64BIT_ADDR_VAL 0xffffffffffff0000UL + +/* For now this just runs as a pre-handler for the real interrupt handler. + * So we just walk through the queue and ACK all the entries, update the + * head pointer, and return. + * + * In the longer term it would be nice to do something more integrated + * wherein we can pass in some of this MSI info to the drivers. This + * would be most useful for PCIe fabric error messages, although we could + * invoke those directly from the loop here in order to pass the info around. + */ +static void pci_msi_prehandler(unsigned int ino, void *data1, void *data2) +{ + unsigned long msiqid, orig_head, head, type_fmt, type; + struct pci_pbm_info *pbm = data1; + struct pci_msiq_entry *base, *ep; + + msiqid = (unsigned long) data2; + + head = fire_read(pbm->pbm_regs + EVENT_QUEUE_HEAD(msiqid)); + + orig_head = head; + base = (pbm->msi_queues + ((msiqid - pbm->msiq_first) * 8192)); + ep = &base[head]; + while ((ep->word0 & MSIQ_WORD0_FMT_TYPE) != 0) { + unsigned long msi_num; + + type_fmt = ((ep->word0 & MSIQ_WORD0_FMT_TYPE) >> + MSIQ_WORD0_FMT_TYPE_SHIFT); + type = (type_fmt >>3); + if (unlikely(type != MSIQ_TYPE_MSI32 && + type != MSIQ_TYPE_MSI64)) + goto bad_type; + + msi_num = ((ep->word0 & MSIQ_WORD0_DATA0) >> + MSIQ_WORD0_DATA0_SHIFT); + + fire_write(pbm->pbm_regs + MSI_CLEAR(msi_num), + MSI_CLEAR_EQWR_N); + + /* Clear the entry. */ + ep->word0 &= ~MSIQ_WORD0_FMT_TYPE; + + /* Go to next entry in ring. */ + head++; + if (head >= pbm->msiq_ent_count) + head = 0; + ep = &base[head]; + } + + if (likely(head != orig_head)) { + /* ACK entries by updating head pointer. */ + fire_write(pbm->pbm_regs + + EVENT_QUEUE_HEAD(msiqid), + head); + } + return; + +bad_type: + printk(KERN_EMERG "MSI: Entry has bad type %lx\n", type); + return; +} + +static int msi_bitmap_alloc(struct pci_pbm_info *pbm) +{ + unsigned long size, bits_per_ulong; + + bits_per_ulong = sizeof(unsigned long) * 8; + size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1); + size /= 8; + BUG_ON(size % sizeof(unsigned long)); + + pbm->msi_bitmap = kzalloc(size, GFP_KERNEL); + if (!pbm->msi_bitmap) + return -ENOMEM; + + return 0; +} + +static void msi_bitmap_free(struct pci_pbm_info *pbm) +{ + kfree(pbm->msi_bitmap); + pbm->msi_bitmap = NULL; +} + +static int msi_queue_alloc(struct pci_pbm_info *pbm) +{ + unsigned long pages, order, i; + + order = get_order(512 * 1024); + pages = __get_free_pages(GFP_KERNEL | __GFP_COMP, order); + if (pages == 0UL) { + printk(KERN_ERR "MSI: Cannot allocate MSI queues (o=%lu).\n", + order); + return -ENOMEM; + } + memset((char *)pages, 0, PAGE_SIZE << order); + pbm->msi_queues = (void *) pages; + + fire_write(pbm->pbm_regs + EVENT_QUEUE_BASE_ADDR_REG, + (EVENT_QUEUE_BASE_ADDR_ALL_ONES | + __pa(pbm->msi_queues))); + + fire_write(pbm->pbm_regs + IMONDO_DATA0, + pbm->portid << 6); + fire_write(pbm->pbm_regs + IMONDO_DATA1, 0); + + fire_write(pbm->pbm_regs + MSI_32BIT_ADDR, + pbm->msi32_start); + fire_write(pbm->pbm_regs + MSI_64BIT_ADDR, + pbm->msi64_start); + + for (i = 0; i < pbm->msiq_num; i++) { + fire_write(pbm->pbm_regs + EVENT_QUEUE_HEAD(i), 0); + fire_write(pbm->pbm_regs + EVENT_QUEUE_TAIL(i), 0); + } + + return 0; +} + +static int alloc_msi(struct pci_pbm_info *pbm) +{ + int i; + + for (i = 0; i < pbm->msi_num; i++) { + if (!test_and_set_bit(i, pbm->msi_bitmap)) + return i + pbm->msi_first; + } + + return -ENOENT; +} + +static void free_msi(struct pci_pbm_info *pbm, int msi_num) +{ + msi_num -= pbm->msi_first; + clear_bit(msi_num, pbm->msi_bitmap); +} + +static int pci_setup_msi_irq(unsigned int *virt_irq_p, + struct pci_dev *pdev, + struct msi_desc *entry) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + unsigned long devino, msiqid, cregs, imap_off; + struct msi_msg msg; + int msi_num, err; + u64 val; + + *virt_irq_p = 0; + + msi_num = alloc_msi(pbm); + if (msi_num < 0) + return msi_num; + + cregs = (unsigned long) pbm->pbm_regs; + + err = sun4u_build_msi(pbm->portid, virt_irq_p, + pbm->msiq_first_devino, + (pbm->msiq_first_devino + + pbm->msiq_num), + cregs + 0x001000UL, + cregs + 0x001400UL); + if (err < 0) + goto out_err; + devino = err; + + imap_off = 0x001000UL + (devino * 0x8UL); + + val = fire_read(pbm->pbm_regs + imap_off); + val |= (1UL << 63) | (1UL << 6); + fire_write(pbm->pbm_regs + imap_off, val); + + msiqid = ((devino - pbm->msiq_first_devino) + + pbm->msiq_first); + + fire_write(pbm->pbm_regs + + EVENT_QUEUE_CONTROL_SET(msiqid), + EVENT_QUEUE_CONTROL_SET_EN); + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi_num)); + val &= ~(MSI_MAP_EQNUM); + val |= msiqid; + fire_write(pbm->pbm_regs + MSI_MAP(msi_num), val); + + fire_write(pbm->pbm_regs + MSI_CLEAR(msi_num), + MSI_CLEAR_EQWR_N); + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi_num)); + val |= MSI_MAP_VALID; + fire_write(pbm->pbm_regs + MSI_MAP(msi_num), val); + + sparc64_set_msi(*virt_irq_p, msi_num); + + if (entry->msi_attrib.is_64) { + msg.address_hi = pbm->msi64_start >> 32; + msg.address_lo = pbm->msi64_start & 0xffffffff; + } else { + msg.address_hi = 0; + msg.address_lo = pbm->msi32_start; + } + msg.data = msi_num; + + set_irq_msi(*virt_irq_p, entry); + write_msi_msg(*virt_irq_p, &msg); + + irq_install_pre_handler(*virt_irq_p, + pci_msi_prehandler, + pbm, (void *) msiqid); + + return 0; + +out_err: + free_msi(pbm, msi_num); + return err; +} + +static void pci_teardown_msi_irq(unsigned int virt_irq, + struct pci_dev *pdev) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + unsigned long msiqid, msi_num; + u64 val; + + msi_num = sparc64_get_msi(virt_irq); + + val = fire_read(pbm->pbm_regs + MSI_MAP(msi_num)); + + msiqid = (val & MSI_MAP_EQNUM); + + val &= ~MSI_MAP_VALID; + fire_write(pbm->pbm_regs + MSI_MAP(msi_num), val); + + fire_write(pbm->pbm_regs + EVENT_QUEUE_CONTROL_CLEAR(msiqid), + EVENT_QUEUE_CONTROL_CLEAR_DIS); + + free_msi(pbm, msi_num); + + /* The sun4u_destroy_msi() will liberate the devino and thus the MSIQ + * allocation. + */ + sun4u_destroy_msi(virt_irq); +} + +static void pci_fire_msi_init(struct pci_pbm_info *pbm) +{ + const u32 *val; + int len; + + val = of_get_property(pbm->prom_node, "#msi-eqs", &len); + if (!val || len != 4) + goto no_msi; + pbm->msiq_num = *val; + if (pbm->msiq_num) { + const struct msiq_prop { + u32 first_msiq; + u32 num_msiq; + u32 first_devino; + } *mqp; + const struct msi_range_prop { + u32 first_msi; + u32 num_msi; + } *mrng; + const struct addr_range_prop { + u32 msi32_high; + u32 msi32_low; + u32 msi32_len; + u32 msi64_high; + u32 msi64_low; + u32 msi64_len; + } *arng; + + val = of_get_property(pbm->prom_node, "msi-eq-size", &len); + if (!val || len != 4) + goto no_msi; + + pbm->msiq_ent_count = *val; + + mqp = of_get_property(pbm->prom_node, + "msi-eq-to-devino", &len); + if (!mqp) + mqp = of_get_property(pbm->prom_node, + "msi-eq-devino", &len); + if (!mqp || len != sizeof(struct msiq_prop)) + goto no_msi; + + pbm->msiq_first = mqp->first_msiq; + pbm->msiq_first_devino = mqp->first_devino; + + val = of_get_property(pbm->prom_node, "#msi", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_num = *val; + + mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); + if (!mrng || len != sizeof(struct msi_range_prop)) + goto no_msi; + pbm->msi_first = mrng->first_msi; + + val = of_get_property(pbm->prom_node, "msi-data-mask", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_data_mask = *val; + + val = of_get_property(pbm->prom_node, "msix-data-width", &len); + if (!val || len != 4) + goto no_msi; + pbm->msix_data_width = *val; + + arng = of_get_property(pbm->prom_node, "msi-address-ranges", + &len); + if (!arng || len != sizeof(struct addr_range_prop)) + goto no_msi; + pbm->msi32_start = ((u64)arng->msi32_high << 32) | + (u64) arng->msi32_low; + pbm->msi64_start = ((u64)arng->msi64_high << 32) | + (u64) arng->msi64_low; + pbm->msi32_len = arng->msi32_len; + pbm->msi64_len = arng->msi64_len; + + if (msi_bitmap_alloc(pbm)) + goto no_msi; + + if (msi_queue_alloc(pbm)) { + msi_bitmap_free(pbm); + goto no_msi; + } + + printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " + "devino[0x%x]\n", + pbm->name, + pbm->msiq_first, pbm->msiq_num, + pbm->msiq_ent_count, + pbm->msiq_first_devino); + printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " + "width[%u]\n", + pbm->name, + pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, + pbm->msix_data_width); + printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " + "addr64[0x%lx:0x%x]\n", + pbm->name, + pbm->msi32_start, pbm->msi32_len, + pbm->msi64_start, pbm->msi64_len); + printk(KERN_INFO "%s: MSI queues at RA [%016lx]\n", + pbm->name, + __pa(pbm->msi_queues)); + } + pbm->setup_msi_irq = pci_setup_msi_irq; + pbm->teardown_msi_irq = pci_teardown_msi_irq; + + return; + +no_msi: + pbm->msiq_num = 0; + printk(KERN_INFO "%s: No MSI support.\n", pbm->name); +} +#else /* CONFIG_PCI_MSI */ +static void pci_fire_msi_init(struct pci_pbm_info *pbm) +{ +} +#endif /* !(CONFIG_PCI_MSI) */ + /* Based at pbm->controller_regs */ #define FIRE_PARITY_CONTROL 0x470010UL #define FIRE_PARITY_ENAB 0x8000000000000000UL @@ -204,6 +641,7 @@ pci_fire_hw_init(pbm); pci_fire_pbm_iommu_init(pbm); + pci_fire_msi_init(pbm); } static inline int portid_compare(u32 x, u32 y) --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/Makefile +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o pci_fire.o -obj-$(CONFIG_SMP) += smp.o trampoline.o +obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o @@ -26,6 +26,7 @@ obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o obj-y += $(obj-yy) --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/sys_sparc.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/sys_sparc.c @@ -436,7 +436,7 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, unsigned long third, void __user *ptr, long fifth) { - int err; + long err; /* No need for backward compatibility. We can start fresh... */ if (call <= SEMCTL) { @@ -453,16 +453,9 @@ err = sys_semget(first, (int)second, (int)third); goto out; case SEMCTL: { - union semun fourth; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if (get_user(fourth.__pad, - (void __user * __user *) ptr)) - goto out; - err = sys_semctl(first, (int)second | IPC_64, - (int)third, fourth); + err = sys_semctl(first, third, + (int)second | IPC_64, + (union semun) ptr); goto out; } default: @@ -555,13 +548,13 @@ if (len >= STACK_TOP32) return -EINVAL; - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + if (addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + if (invalid_64bit_range(addr, len)) return -EINVAL; } --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/prom.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/prom.c @@ -276,6 +276,21 @@ } EXPORT_SYMBOL(of_set_property); +int of_find_in_proplist(const char *list, const char *match, int len) +{ + while (len > 0) { + int l; + + if (!strcmp(list, match)) + return 1; + l = strlen(list) + 1; + list += l; + len -= l; + } + return 0; +} +EXPORT_SYMBOL(of_find_in_proplist); + static unsigned int prom_early_allocated; static void * __init prom_early_alloc(unsigned long size) @@ -1200,7 +1215,8 @@ if (!strcmp(dp->name, "fhc") && !strcmp(dp->parent->name, "central")) return central_irq_trans_init(dp); - if (!strcmp(dp->name, "virtual-devices")) + if (!strcmp(dp->name, "virtual-devices") || + !strcmp(dp->name, "niu")) return sun4v_vdev_irq_trans_init(dp); } @@ -1737,8 +1753,12 @@ ncpus_probed++; #ifdef CONFIG_SMP - if (cpuid >= NR_CPUS) + if (cpuid >= NR_CPUS) { + printk(KERN_WARNING "Ignoring CPU %d which is " + ">= NR_CPUS (%d)\n", + cpuid, NR_CPUS); continue; + } #else /* On uniprocessor we only want the values for the * real physical cpu the kernel booted onto, however @@ -1808,13 +1828,67 @@ #ifdef CONFIG_SMP cpu_set(cpuid, cpu_present_map); - cpu_set(cpuid, phys_cpu_present_map); + cpu_set(cpuid, cpu_possible_map); #endif } smp_fill_in_sib_core_maps(); } +struct device_node *of_console_device; +EXPORT_SYMBOL(of_console_device); + +char *of_console_path; +EXPORT_SYMBOL(of_console_path); + +char *of_console_options; +EXPORT_SYMBOL(of_console_options); + +static void __init of_console_init(void) +{ + char *msg = "OF stdout device is: %s\n"; + struct device_node *dp; + const char *type; + phandle node; + + of_console_path = prom_early_alloc(256); + if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) { + prom_printf("Cannot obtain path of stdout.\n"); + prom_halt(); + } + of_console_options = strrchr(of_console_path, ':'); + if (of_console_options) { + of_console_options++; + if (*of_console_options == '\0') + of_console_options = NULL; + } + + node = prom_inst2pkg(prom_stdout); + if (!node) { + prom_printf("Cannot resolve stdout node from " + "instance %08x.\n", prom_stdout); + prom_halt(); + } + + dp = of_find_node_by_phandle(node); + type = of_get_property(dp, "device_type", NULL); + if (!type) { + prom_printf("Console stdout lacks device_type property.\n"); + prom_halt(); + } + + if (strcmp(type, "display") && strcmp(type, "serial")) { + prom_printf("Console device_type is neither display " + "nor serial.\n"); + prom_halt(); + } + + of_console_device = dp; + + prom_printf(msg, of_console_path); + printk(msg, of_console_path); +} + void __init prom_build_devicetree(void) { struct device_node **nextp; @@ -1827,6 +1901,8 @@ allnodes->child = build_tree(allnodes, prom_getchild(allnodes->node), &nextp); + of_console_init(); + printk("PROM: Built device tree with %u bytes of memory.\n", prom_early_allocated); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/mdesc.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/mdesc.c @@ -6,6 +6,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -29,7 +33,7 @@ u32 node_sz; /* node block size */ u32 name_sz; /* name block size */ u32 data_sz; /* data block size */ -}; +} __attribute__((aligned(16))); struct mdesc_elem { u8 tag; @@ -53,338 +57,536 @@ } d; }; -static struct mdesc_hdr *main_mdesc; -static struct mdesc_node *allnodes; +struct mdesc_mem_ops { + struct mdesc_handle *(*alloc)(unsigned int mdesc_size); + void (*free)(struct mdesc_handle *handle); +}; + +struct mdesc_handle { + struct list_head list; + struct mdesc_mem_ops *mops; + void *self_base; + atomic_t refcnt; + unsigned int handle_size; + struct mdesc_hdr mdesc; +}; -static struct mdesc_node *allnodes_tail; -static unsigned int unique_id; +static void mdesc_handle_init(struct mdesc_handle *hp, + unsigned int handle_size, + void *base) +{ + BUG_ON(((unsigned long)&hp->mdesc) & (16UL - 1)); -static struct mdesc_node **mdesc_hash; -static unsigned int mdesc_hash_size; + memset(hp, 0, handle_size); + INIT_LIST_HEAD(&hp->list); + hp->self_base = base; + atomic_set(&hp->refcnt, 1); + hp->handle_size = handle_size; +} -static inline unsigned int node_hashfn(u64 node) +static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size) { - return ((unsigned int) (node ^ (node >> 8) ^ (node >> 16))) - & (mdesc_hash_size - 1); + struct mdesc_handle *hp; + unsigned int handle_size, alloc_size; + + handle_size = (sizeof(struct mdesc_handle) - + sizeof(struct mdesc_hdr) + + mdesc_size); + alloc_size = PAGE_ALIGN(handle_size); + + hp = __alloc_bootmem(alloc_size, PAGE_SIZE, 0UL); + if (hp) + mdesc_handle_init(hp, handle_size, hp); + + return hp; } -static inline void hash_node(struct mdesc_node *mp) +static void mdesc_bootmem_free(struct mdesc_handle *hp) { - struct mdesc_node **head = &mdesc_hash[node_hashfn(mp->node)]; + unsigned int alloc_size, handle_size = hp->handle_size; + unsigned long start, end; - mp->hash_next = *head; - *head = mp; + BUG_ON(atomic_read(&hp->refcnt) != 0); + BUG_ON(!list_empty(&hp->list)); - if (allnodes_tail) { - allnodes_tail->allnodes_next = mp; - allnodes_tail = mp; - } else { - allnodes = allnodes_tail = mp; + alloc_size = PAGE_ALIGN(handle_size); + + start = (unsigned long) hp; + end = start + alloc_size; + + while (start < end) { + struct page *p; + + p = virt_to_page(start); + ClearPageReserved(p); + __free_page(p); + start += PAGE_SIZE; } } -static struct mdesc_node *find_node(u64 node) +static struct mdesc_mem_ops bootmem_mdesc_ops = { + .alloc = mdesc_bootmem_alloc, + .free = mdesc_bootmem_free, +}; + +static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) { - struct mdesc_node *mp = mdesc_hash[node_hashfn(node)]; + unsigned int handle_size; + void *base; - while (mp) { - if (mp->node == node) - return mp; + handle_size = (sizeof(struct mdesc_handle) - + sizeof(struct mdesc_hdr) + + mdesc_size); + + base = kmalloc(handle_size + 15, GFP_KERNEL | __GFP_NOFAIL); + if (base) { + struct mdesc_handle *hp; + unsigned long addr; + + addr = (unsigned long)base; + addr = (addr + 15UL) & ~15UL; + hp = (struct mdesc_handle *) addr; - mp = mp->hash_next; + mdesc_handle_init(hp, handle_size, base); + return hp; } + return NULL; } -struct property *md_find_property(const struct mdesc_node *mp, - const char *name, - int *lenp) +static void mdesc_kfree(struct mdesc_handle *hp) { - struct property *pp; + BUG_ON(atomic_read(&hp->refcnt) != 0); + BUG_ON(!list_empty(&hp->list)); - for (pp = mp->properties; pp != 0; pp = pp->next) { - if (strcasecmp(pp->name, name) == 0) { - if (lenp) - *lenp = pp->length; - break; - } - } - return pp; + kfree(hp->self_base); } -EXPORT_SYMBOL(md_find_property); -/* - * Find a property with a given name for a given node - * and return the value. - */ -const void *md_get_property(const struct mdesc_node *mp, const char *name, - int *lenp) +static struct mdesc_mem_ops kmalloc_mdesc_memops = { + .alloc = mdesc_kmalloc, + .free = mdesc_kfree, +}; + +static struct mdesc_handle *mdesc_alloc(unsigned int mdesc_size, + struct mdesc_mem_ops *mops) { - struct property *pp = md_find_property(mp, name, lenp); - return pp ? pp->value : NULL; + struct mdesc_handle *hp = mops->alloc(mdesc_size); + + if (hp) + hp->mops = mops; + + return hp; } -EXPORT_SYMBOL(md_get_property); -struct mdesc_node *md_find_node_by_name(struct mdesc_node *from, - const char *name) +static void mdesc_free(struct mdesc_handle *hp) { - struct mdesc_node *mp; + hp->mops->free(hp); +} - mp = from ? from->allnodes_next : allnodes; - for (; mp != NULL; mp = mp->allnodes_next) { - if (strcmp(mp->name, name) == 0) - break; +static struct mdesc_handle *cur_mdesc; +static LIST_HEAD(mdesc_zombie_list); +static DEFINE_SPINLOCK(mdesc_lock); + +struct mdesc_handle *mdesc_grab(void) +{ + struct mdesc_handle *hp; + unsigned long flags; + + spin_lock_irqsave(&mdesc_lock, flags); + hp = cur_mdesc; + if (hp) + atomic_inc(&hp->refcnt); + spin_unlock_irqrestore(&mdesc_lock, flags); + + return hp; +} +EXPORT_SYMBOL(mdesc_grab); + +void mdesc_release(struct mdesc_handle *hp) +{ + unsigned long flags; + + spin_lock_irqsave(&mdesc_lock, flags); + if (atomic_dec_and_test(&hp->refcnt)) { + list_del_init(&hp->list); + hp->mops->free(hp); } - return mp; + spin_unlock_irqrestore(&mdesc_lock, flags); } -EXPORT_SYMBOL(md_find_node_by_name); +EXPORT_SYMBOL(mdesc_release); -static unsigned int mdesc_early_allocated; +static DEFINE_MUTEX(mdesc_mutex); +static struct mdesc_notifier_client *client_list; -static void * __init mdesc_early_alloc(unsigned long size) +void mdesc_register_notifier(struct mdesc_notifier_client *client) { - void *ret; + u64 node; - ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); - if (ret == NULL) { - prom_printf("MDESC: alloc of %lu bytes failed.\n", size); - prom_halt(); + mutex_lock(&mdesc_mutex); + client->next = client_list; + client_list = client; + + mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name) + client->add(cur_mdesc, node); + + mutex_unlock(&mdesc_mutex); +} + +static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node) +{ + const u64 *id; + u64 a; + + id = NULL; + mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { + u64 target; + + target = mdesc_arc_target(hp, a); + id = mdesc_get_property(hp, target, + "cfg-handle", NULL); + if (id) + break; } - memset(ret, 0, size); + return id; +} - mdesc_early_allocated += size; +/* Run 'func' on nodes which are in A but not in B. */ +static void invoke_on_missing(const char *name, + struct mdesc_handle *a, + struct mdesc_handle *b, + void (*func)(struct mdesc_handle *, u64)) +{ + u64 node; - return ret; + mdesc_for_each_node_by_name(a, node, name) { + int found = 0, is_vdc_port = 0; + const char *name_prop; + const u64 *id; + u64 fnode; + + name_prop = mdesc_get_property(a, node, "name", NULL); + if (name_prop && !strcmp(name_prop, "vdc-port")) { + is_vdc_port = 1; + id = parent_cfg_handle(a, node); + } else + id = mdesc_get_property(a, node, "id", NULL); + + if (!id) { + printk(KERN_ERR "MD: Cannot find ID for %s node.\n", + (name_prop ? name_prop : name)); + continue; + } + + mdesc_for_each_node_by_name(b, fnode, name) { + const u64 *fid; + + if (is_vdc_port) { + name_prop = mdesc_get_property(b, fnode, + "name", NULL); + if (!name_prop || + strcmp(name_prop, "vdc-port")) + continue; + fid = parent_cfg_handle(b, fnode); + if (!fid) { + printk(KERN_ERR "MD: Cannot find ID " + "for vdc-port node.\n"); + continue; + } + } else + fid = mdesc_get_property(b, fnode, + "id", NULL); + + if (*id == *fid) { + found = 1; + break; + } + } + if (!found) + func(a, node); + } } -static unsigned int __init count_arcs(struct mdesc_elem *ep) +static void notify_one(struct mdesc_notifier_client *p, + struct mdesc_handle *old_hp, + struct mdesc_handle *new_hp) { - unsigned int ret = 0; + invoke_on_missing(p->node_name, old_hp, new_hp, p->remove); + invoke_on_missing(p->node_name, new_hp, old_hp, p->add); +} - ep++; - while (ep->tag != MD_NODE_END) { - if (ep->tag == MD_PROP_ARC) - ret++; - ep++; +static void mdesc_notify_clients(struct mdesc_handle *old_hp, + struct mdesc_handle *new_hp) +{ + struct mdesc_notifier_client *p = client_list; + + while (p) { + notify_one(p, old_hp, new_hp); + p = p->next; } - return ret; } -static void __init mdesc_node_alloc(u64 node, struct mdesc_elem *ep, const char *names) +void mdesc_update(void) { - unsigned int num_arcs = count_arcs(ep); - struct mdesc_node *mp; + unsigned long len, real_len, status; + struct mdesc_handle *hp, *orig_hp; + unsigned long flags; + + mutex_lock(&mdesc_mutex); - mp = mdesc_early_alloc(sizeof(*mp) + - (num_arcs * sizeof(struct mdesc_arc))); - mp->name = names + ep->name_offset; - mp->node = node; - mp->unique_id = unique_id++; - mp->num_arcs = num_arcs; + (void) sun4v_mach_desc(0UL, 0UL, &len); + + hp = mdesc_alloc(len, &kmalloc_mdesc_memops); + if (!hp) { + printk(KERN_ERR "MD: mdesc alloc fails\n"); + goto out; + } + + status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); + if (status != HV_EOK || real_len > len) { + printk(KERN_ERR "MD: mdesc reread fails with %lu\n", + status); + atomic_dec(&hp->refcnt); + mdesc_free(hp); + goto out; + } - hash_node(mp); + spin_lock_irqsave(&mdesc_lock, flags); + orig_hp = cur_mdesc; + cur_mdesc = hp; + spin_unlock_irqrestore(&mdesc_lock, flags); + + mdesc_notify_clients(orig_hp, hp); + + spin_lock_irqsave(&mdesc_lock, flags); + if (atomic_dec_and_test(&orig_hp->refcnt)) + mdesc_free(orig_hp); + else + list_add(&orig_hp->list, &mdesc_zombie_list); + spin_unlock_irqrestore(&mdesc_lock, flags); + +out: + mutex_unlock(&mdesc_mutex); } -static inline struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) +static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) { return (struct mdesc_elem *) (mdesc + 1); } -static inline void *name_block(struct mdesc_hdr *mdesc) +static void *name_block(struct mdesc_hdr *mdesc) { return ((void *) node_block(mdesc)) + mdesc->node_sz; } -static inline void *data_block(struct mdesc_hdr *mdesc) +static void *data_block(struct mdesc_hdr *mdesc) { return ((void *) name_block(mdesc)) + mdesc->name_sz; } -/* In order to avoid recursion (the graph can be very deep) we use a - * two pass algorithm. First we allocate all the nodes and hash them. - * Then we iterate over each node, filling in the arcs and properties. - */ -static void __init build_all_nodes(struct mdesc_hdr *mdesc) +u64 mdesc_node_by_name(struct mdesc_handle *hp, + u64 from_node, const char *name) { - struct mdesc_elem *start, *ep; - struct mdesc_node *mp; - const char *names; - void *data; - u64 last_node; + struct mdesc_elem *ep = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + u64 ret; + + if (from_node == MDESC_NODE_NULL) { + ret = from_node = 0; + } else if (from_node >= last_node) { + return MDESC_NODE_NULL; + } else { + ret = ep[from_node].d.val; + } - start = ep = node_block(mdesc); - last_node = mdesc->node_sz / 16; + while (ret < last_node) { + if (ep[ret].tag != MD_NODE) + return MDESC_NODE_NULL; + if (!strcmp(names + ep[ret].name_offset, name)) + break; + ret = ep[ret].d.val; + } + if (ret >= last_node) + ret = MDESC_NODE_NULL; + return ret; +} +EXPORT_SYMBOL(mdesc_node_by_name); - names = name_block(mdesc); +const void *mdesc_get_property(struct mdesc_handle *hp, u64 node, + const char *name, int *lenp) +{ + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + void *data = data_block(&hp->mdesc); + struct mdesc_elem *ep; - while (1) { - u64 node = ep - start; + if (node == MDESC_NODE_NULL || node >= last_node) + return NULL; - if (ep->tag == MD_LIST_END) + ep = node_block(&hp->mdesc) + node; + ep++; + for (; ep->tag != MD_NODE_END; ep++) { + void *val = NULL; + int len = 0; + + switch (ep->tag) { + case MD_PROP_VAL: + val = &ep->d.val; + len = 8; break; - if (ep->tag != MD_NODE) { - prom_printf("MDESC: Inconsistent element list.\n"); - prom_halt(); - } - - mdesc_node_alloc(node, ep, names); + case MD_PROP_STR: + case MD_PROP_DATA: + val = data + ep->d.data.data_offset; + len = ep->d.data.data_len; + break; - if (ep->d.val >= last_node) { - printk("MDESC: Warning, early break out of node scan.\n"); - printk("MDESC: Next node [%lu] last_node [%lu].\n", - node, last_node); + default: break; } + if (!val) + continue; - ep = start + ep->d.val; + if (!strcmp(names + ep->name_offset, name)) { + if (lenp) + *lenp = len; + return val; + } } - data = data_block(mdesc); - for (mp = allnodes; mp; mp = mp->allnodes_next) { - struct mdesc_elem *ep = start + mp->node; - struct property **link = &mp->properties; - unsigned int this_arc = 0; - - ep++; - while (ep->tag != MD_NODE_END) { - switch (ep->tag) { - case MD_PROP_ARC: { - struct mdesc_node *target; - - if (this_arc >= mp->num_arcs) { - prom_printf("MDESC: ARC overrun [%u:%u]\n", - this_arc, mp->num_arcs); - prom_halt(); - } - target = find_node(ep->d.val); - if (!target) { - printk("MDESC: Warning, arc points to " - "missing node, ignoring.\n"); - break; - } - mp->arcs[this_arc].name = - (names + ep->name_offset); - mp->arcs[this_arc].arc = target; - this_arc++; - break; - } + return NULL; +} +EXPORT_SYMBOL(mdesc_get_property); - case MD_PROP_VAL: - case MD_PROP_STR: - case MD_PROP_DATA: { - struct property *p = mdesc_early_alloc(sizeof(*p)); - - p->unique_id = unique_id++; - p->name = (char *) names + ep->name_offset; - if (ep->tag == MD_PROP_VAL) { - p->value = &ep->d.val; - p->length = 8; - } else { - p->value = data + ep->d.data.data_offset; - p->length = ep->d.data.data_len; - } - *link = p; - link = &p->next; - break; - } +u64 mdesc_next_arc(struct mdesc_handle *hp, u64 from, const char *arc_type) +{ + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; - case MD_NOOP: - break; + if (from == MDESC_NODE_NULL || from >= last_node) + return MDESC_NODE_NULL; - default: - printk("MDESC: Warning, ignoring unknown tag type %02x\n", - ep->tag); - } - ep++; - } + ep = base + from; + + ep++; + for (; ep->tag != MD_NODE_END; ep++) { + if (ep->tag != MD_PROP_ARC) + continue; + + if (strcmp(names + ep->name_offset, arc_type)) + continue; + + return ep - base; } + + return MDESC_NODE_NULL; } +EXPORT_SYMBOL(mdesc_next_arc); -static unsigned int __init count_nodes(struct mdesc_hdr *mdesc) +u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc) { - struct mdesc_elem *ep = node_block(mdesc); - struct mdesc_elem *end; - unsigned int cnt = 0; - - end = ((void *)ep) + mdesc->node_sz; - while (ep < end) { - if (ep->tag == MD_NODE) - cnt++; - ep++; - } - return cnt; + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + + ep = base + arc; + + return ep->d.val; } +EXPORT_SYMBOL(mdesc_arc_target); + +const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) +{ + struct mdesc_elem *ep, *base = node_block(&hp->mdesc); + const char *names = name_block(&hp->mdesc); + u64 last_node = hp->mdesc.node_sz / 16; + + if (node == MDESC_NODE_NULL || node >= last_node) + return NULL; + + ep = base + node; + if (ep->tag != MD_NODE) + return NULL; + + return names + ep->name_offset; +} +EXPORT_SYMBOL(mdesc_node_name); static void __init report_platform_properties(void) { - struct mdesc_node *pn = md_find_node_by_name(NULL, "platform"); + struct mdesc_handle *hp = mdesc_grab(); + u64 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform"); const char *s; const u64 *v; - if (!pn) { + if (pn == MDESC_NODE_NULL) { prom_printf("No platform node in machine-description.\n"); prom_halt(); } - s = md_get_property(pn, "banner-name", NULL); + s = mdesc_get_property(hp, pn, "banner-name", NULL); printk("PLATFORM: banner-name [%s]\n", s); - s = md_get_property(pn, "name", NULL); + s = mdesc_get_property(hp, pn, "name", NULL); printk("PLATFORM: name [%s]\n", s); - v = md_get_property(pn, "hostid", NULL); + v = mdesc_get_property(hp, pn, "hostid", NULL); if (v) printk("PLATFORM: hostid [%08lx]\n", *v); - v = md_get_property(pn, "serial#", NULL); + v = mdesc_get_property(hp, pn, "serial#", NULL); if (v) printk("PLATFORM: serial# [%08lx]\n", *v); - v = md_get_property(pn, "stick-frequency", NULL); + v = mdesc_get_property(hp, pn, "stick-frequency", NULL); printk("PLATFORM: stick-frequency [%08lx]\n", *v); - v = md_get_property(pn, "mac-address", NULL); + v = mdesc_get_property(hp, pn, "mac-address", NULL); if (v) printk("PLATFORM: mac-address [%lx]\n", *v); - v = md_get_property(pn, "watchdog-resolution", NULL); + v = mdesc_get_property(hp, pn, "watchdog-resolution", NULL); if (v) printk("PLATFORM: watchdog-resolution [%lu ms]\n", *v); - v = md_get_property(pn, "watchdog-max-timeout", NULL); + v = mdesc_get_property(hp, pn, "watchdog-max-timeout", NULL); if (v) printk("PLATFORM: watchdog-max-timeout [%lu ms]\n", *v); - v = md_get_property(pn, "max-cpus", NULL); + v = mdesc_get_property(hp, pn, "max-cpus", NULL); if (v) printk("PLATFORM: max-cpus [%lu]\n", *v); -} -static int inline find_in_proplist(const char *list, const char *match, int len) -{ - while (len > 0) { - int l; +#ifdef CONFIG_SMP + { + int max_cpu, i; - if (!strcmp(list, match)) - return 1; - l = strlen(list) + 1; - list += l; - len -= l; + if (v) { + max_cpu = *v; + if (max_cpu > NR_CPUS) + max_cpu = NR_CPUS; + } else { + max_cpu = NR_CPUS; + } + for (i = 0; i < max_cpu; i++) + cpu_set(i, cpu_possible_map); } - return 0; +#endif + + mdesc_release(hp); } -static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp) +static void __devinit fill_in_one_cache(cpuinfo_sparc *c, + struct mdesc_handle *hp, + u64 mp) { - const u64 *level = md_get_property(mp, "level", NULL); - const u64 *size = md_get_property(mp, "size", NULL); - const u64 *line_size = md_get_property(mp, "line-size", NULL); + const u64 *level = mdesc_get_property(hp, mp, "level", NULL); + const u64 *size = mdesc_get_property(hp, mp, "size", NULL); + const u64 *line_size = mdesc_get_property(hp, mp, "line-size", NULL); const char *type; int type_len; - type = md_get_property(mp, "type", &type_len); + type = mdesc_get_property(hp, mp, "type", &type_len); switch (*level) { case 1: - if (find_in_proplist(type, "instn", type_len)) { + if (of_find_in_proplist(type, "instn", type_len)) { c->icache_size = *size; c->icache_line_size = *line_size; - } else if (find_in_proplist(type, "data", type_len)) { + } else if (of_find_in_proplist(type, "data", type_len)) { c->dcache_size = *size; c->dcache_line_size = *line_size; } @@ -400,48 +602,45 @@ } if (*level == 1) { - unsigned int i; - - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + u64 a; - if (strcmp(mp->arcs[i].name, "fwd")) - continue; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 target = mdesc_arc_target(hp, a); + const char *name = mdesc_node_name(hp, target); - if (!strcmp(t->name, "cache")) - fill_in_one_cache(c, t); + if (!strcmp(name, "cache")) + fill_in_one_cache(c, hp, target); } } } -static void __init mark_core_ids(struct mdesc_node *mp, int core_id) +static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp, + int core_id) { - unsigned int i; + u64 a; - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { + u64 t = mdesc_arc_target(hp, a); + const char *name; const u64 *id; - if (strcmp(mp->arcs[i].name, "back")) - continue; - - if (!strcmp(t->name, "cpu")) { - id = md_get_property(t, "id", NULL); + name = mdesc_node_name(hp, t); + if (!strcmp(name, "cpu")) { + id = mdesc_get_property(hp, t, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).core_id = core_id; } else { - unsigned int j; + u64 j; - for (j = 0; j < t->num_arcs; j++) { - struct mdesc_node *n = t->arcs[j].arc; + mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { + u64 n = mdesc_arc_target(hp, j); + const char *n_name; - if (strcmp(t->arcs[j].name, "back")) + n_name = mdesc_node_name(hp, n); + if (strcmp(n_name, "cpu")) continue; - if (strcmp(n->name, "cpu")) - continue; - - id = md_get_property(n, "id", NULL); + id = mdesc_get_property(hp, n, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).core_id = core_id; } @@ -449,78 +648,81 @@ } } -static void __init set_core_ids(void) +static void __devinit set_core_ids(struct mdesc_handle *hp) { - struct mdesc_node *mp; int idx; + u64 mp; idx = 1; - md_for_each_node_by_name(mp, "cache") { - const u64 *level = md_get_property(mp, "level", NULL); + mdesc_for_each_node_by_name(hp, mp, "cache") { + const u64 *level; const char *type; int len; + level = mdesc_get_property(hp, mp, "level", NULL); if (*level != 1) continue; - type = md_get_property(mp, "type", &len); - if (!find_in_proplist(type, "instn", len)) + type = mdesc_get_property(hp, mp, "type", &len); + if (!of_find_in_proplist(type, "instn", len)) continue; - mark_core_ids(mp, idx); + mark_core_ids(hp, mp, idx); idx++; } } -static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id) +static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, + int proc_id) { - int i; + u64 a; - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { + u64 t = mdesc_arc_target(hp, a); + const char *name; const u64 *id; - if (strcmp(mp->arcs[i].name, "back")) + name = mdesc_node_name(hp, t); + if (strcmp(name, "cpu")) continue; - if (strcmp(t->name, "cpu")) - continue; - - id = md_get_property(t, "id", NULL); + id = mdesc_get_property(hp, t, "id", NULL); if (*id < NR_CPUS) cpu_data(*id).proc_id = proc_id; } } -static void __init __set_proc_ids(const char *exec_unit_name) +static void __devinit __set_proc_ids(struct mdesc_handle *hp, + const char *exec_unit_name) { - struct mdesc_node *mp; int idx; + u64 mp; idx = 0; - md_for_each_node_by_name(mp, exec_unit_name) { + mdesc_for_each_node_by_name(hp, mp, exec_unit_name) { const char *type; int len; - type = md_get_property(mp, "type", &len); - if (!find_in_proplist(type, "int", len) && - !find_in_proplist(type, "integer", len)) + type = mdesc_get_property(hp, mp, "type", &len); + if (!of_find_in_proplist(type, "int", len) && + !of_find_in_proplist(type, "integer", len)) continue; - mark_proc_ids(mp, idx); + mark_proc_ids(hp, mp, idx); idx++; } } -static void __init set_proc_ids(void) +static void __devinit set_proc_ids(struct mdesc_handle *hp) { - __set_proc_ids("exec_unit"); - __set_proc_ids("exec-unit"); + __set_proc_ids(hp, "exec_unit"); + __set_proc_ids(hp, "exec-unit"); } -static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) +static void __devinit get_one_mondo_bits(const u64 *p, unsigned int *mask, + unsigned char def) { u64 val; @@ -538,42 +740,50 @@ *mask = ((1U << def) * 64U) - 1U; } -static void __init get_mondo_data(struct mdesc_node *mp, struct trap_per_cpu *tb) +static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, + struct trap_per_cpu *tb) { const u64 *val; - val = md_get_property(mp, "q-cpu-mondo-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); - val = md_get_property(mp, "q-dev-mondo-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); - val = md_get_property(mp, "q-resumable-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); get_one_mondo_bits(val, &tb->resum_qmask, 6); - val = md_get_property(mp, "q-nonresumable-#bits", NULL); + val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -static void __init mdesc_fill_in_cpu_data(void) +void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) { - struct mdesc_node *mp; + struct mdesc_handle *hp = mdesc_grab(); + u64 mp; ncpus_probed = 0; - md_for_each_node_by_name(mp, "cpu") { - const u64 *id = md_get_property(mp, "id", NULL); - const u64 *cfreq = md_get_property(mp, "clock-frequency", NULL); + mdesc_for_each_node_by_name(hp, mp, "cpu") { + const u64 *id = mdesc_get_property(hp, mp, "id", NULL); + const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL); struct trap_per_cpu *tb; cpuinfo_sparc *c; - unsigned int i; int cpuid; + u64 a; ncpus_probed++; cpuid = *id; #ifdef CONFIG_SMP - if (cpuid >= NR_CPUS) + if (cpuid >= NR_CPUS) { + printk(KERN_WARNING "Ignoring CPU %d which is " + ">= NR_CPUS (%d)\n", + cpuid, NR_CPUS); + continue; + } + if (!cpu_isset(cpuid, mask)) continue; #else /* On uniprocessor we only want the values for the @@ -589,35 +799,30 @@ c->clock_tick = *cfreq; tb = &trap_block[cpuid]; - get_mondo_data(mp, tb); - - for (i = 0; i < mp->num_arcs; i++) { - struct mdesc_node *t = mp->arcs[i].arc; - unsigned int j; + get_mondo_data(hp, mp, tb); - if (strcmp(mp->arcs[i].name, "fwd")) - continue; - - if (!strcmp(t->name, "cache")) { - fill_in_one_cache(c, t); + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 j, t = mdesc_arc_target(hp, a); + const char *t_name; + + t_name = mdesc_node_name(hp, t); + if (!strcmp(t_name, "cache")) { + fill_in_one_cache(c, hp, t); continue; } - for (j = 0; j < t->num_arcs; j++) { - struct mdesc_node *n; - - n = t->arcs[j].arc; - if (strcmp(t->arcs[j].name, "fwd")) - continue; - - if (!strcmp(n->name, "cache")) - fill_in_one_cache(c, n); + mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) { + u64 n = mdesc_arc_target(hp, j); + const char *n_name; + + n_name = mdesc_node_name(hp, n); + if (!strcmp(n_name, "cache")) + fill_in_one_cache(c, hp, n); } } #ifdef CONFIG_SMP cpu_set(cpuid, cpu_present_map); - cpu_set(cpuid, phys_cpu_present_map); #endif c->core_id = 0; @@ -628,45 +833,80 @@ sparc64_multi_core = 1; #endif - set_core_ids(); - set_proc_ids(); + set_core_ids(hp); + set_proc_ids(hp); smp_fill_in_sib_core_maps(); + + mdesc_release(hp); } +static ssize_t mdesc_read(struct file *file, char __user *buf, + size_t len, loff_t *offp) +{ + struct mdesc_handle *hp = mdesc_grab(); + int err; + + if (!hp) + return -ENODEV; + + err = hp->handle_size; + if (len < hp->handle_size) + err = -EMSGSIZE; + else if (copy_to_user(buf, &hp->mdesc, hp->handle_size)) + err = -EFAULT; + mdesc_release(hp); + + return err; +} + +static const struct file_operations mdesc_fops = { + .read = mdesc_read, + .owner = THIS_MODULE, +}; + +static struct miscdevice mdesc_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mdesc", + .fops = &mdesc_fops, +}; + +static int __init mdesc_misc_init(void) +{ + return misc_register(&mdesc_misc); +} + +__initcall(mdesc_misc_init); + void __init sun4v_mdesc_init(void) { + struct mdesc_handle *hp; unsigned long len, real_len, status; + cpumask_t mask; (void) sun4v_mach_desc(0UL, 0UL, &len); printk("MDESC: Size is %lu bytes.\n", len); - main_mdesc = mdesc_early_alloc(len); + hp = mdesc_alloc(len, &bootmem_mdesc_ops); + if (hp == NULL) { + prom_printf("MDESC: alloc of %lu bytes failed.\n", len); + prom_halt(); + } - status = sun4v_mach_desc(__pa(main_mdesc), len, &real_len); + status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); if (status != HV_EOK || real_len > len) { prom_printf("sun4v_mach_desc fails, err(%lu), " "len(%lu), real_len(%lu)\n", status, len, real_len); + mdesc_free(hp); prom_halt(); } - len = count_nodes(main_mdesc); - printk("MDESC: %lu nodes.\n", len); - - len = roundup_pow_of_two(len); - - mdesc_hash = mdesc_early_alloc(len * sizeof(struct mdesc_node *)); - mdesc_hash_size = len; - - printk("MDESC: Hash size %lu entries.\n", len); - - build_all_nodes(main_mdesc); - - printk("MDESC: Built graph with %u bytes of memory.\n", - mdesc_early_allocated); + cur_mdesc = hp; report_platform_properties(); - mdesc_fill_in_cpu_data(); + + cpus_setall(mask); + mdesc_fill_in_cpu_data(mask); } --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/hvtramp.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/hvtramp.S @@ -0,0 +1,137 @@ +/* hvtramp.S: Hypervisor start-cpu trampoline code. + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + .text + .align 8 + .globl hv_cpu_startup, hv_cpu_startup_end + + /* This code executes directly out of the hypervisor + * with physical addressing (va==pa). %o0 contains + * our client argument which for Linux points to + * a descriptor data structure which defines the + * MMU entries we need to load up. + * + * After we set things up we enable the MMU and call + * into the kernel. + * + * First setup basic privileged cpu state. + */ +hv_cpu_startup: + SET_GL(0) + wrpr %g0, 15, %pil + wrpr %g0, 0, %canrestore + wrpr %g0, 0, %otherwin + wrpr %g0, 6, %cansave + wrpr %g0, 6, %cleanwin + wrpr %g0, 0, %cwp + wrpr %g0, 0, %wstate + wrpr %g0, 0, %tl + + sethi %hi(sparc64_ttable_tl0), %g1 + wrpr %g1, %tba + + mov %o0, %l0 + + lduw [%l0 + HVTRAMP_DESCR_CPU], %g1 + mov SCRATCHPAD_CPUID, %g2 + stxa %g1, [%g2] ASI_SCRATCHPAD + + ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_VA], %g2 + stxa %g2, [%g0] ASI_SCRATCHPAD + + mov 0, %l1 + lduw [%l0 + HVTRAMP_DESCR_NUM_MAPPINGS], %l2 + add %l0, HVTRAMP_DESCR_MAPS, %l3 + +1: ldx [%l3 + HVTRAMP_MAPPING_VADDR], %o0 + clr %o1 + ldx [%l3 + HVTRAMP_MAPPING_TTE], %o2 + mov HV_MMU_IMMU | HV_MMU_DMMU, %o3 + mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 + ta HV_FAST_TRAP + + brnz,pn %o0, 80f + nop + + add %l1, 1, %l1 + cmp %l1, %l2 + blt,a,pt %xcc, 1b + add %l3, HVTRAMP_MAPPING_SIZE, %l3 + + ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_PA], %o0 + mov HV_FAST_MMU_FAULT_AREA_CONF, %o5 + ta HV_FAST_TRAP + + brnz,pn %o0, 80f + nop + + wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate + + ldx [%l0 + HVTRAMP_DESCR_THREAD_REG], %l6 + + mov 1, %o0 + set 1f, %o1 + mov HV_FAST_MMU_ENABLE, %o5 + ta HV_FAST_TRAP + + ba,pt %xcc, 80f + nop + +1: + wr %g0, 0, %fprs + wr %g0, ASI_P, %asi + + mov PRIMARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_MMU + membar #Sync + + mov SECONDARY_CONTEXT, %g7 + stxa %g0, [%g7] ASI_MMU + membar #Sync + + mov %l6, %g6 + ldx [%g6 + TI_TASK], %g4 + + mov 1, %g5 + sllx %g5, THREAD_SHIFT, %g5 + sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 + add %g6, %g5, %sp + mov 0, %fp + + call init_irqwork_curcpu + nop + call hard_smp_processor_id + nop + + call sun4v_register_mondo_queues + nop + + call init_cur_cpu_trap + mov %g6, %o0 + + wrpr %g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate + + call smp_callin + nop + call cpu_idle + mov 0, %o0 + call cpu_panic + nop + +80: ba,pt %xcc, 80b + nop + + .align 8 +hv_cpu_startup_end: --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/process.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/process.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,7 @@ /* #define VERBOSE_SHOWREGS */ -static void sparc64_yield(void) +static void sparc64_yield(int cpu) { if (tlb_type != hypervisor) return; @@ -57,7 +58,7 @@ clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); - while (!need_resched()) { + while (!need_resched() && !cpu_is_offline(cpu)) { unsigned long pstate; /* Disable interrupts. */ @@ -68,7 +69,7 @@ : "=&r" (pstate) : "i" (PSTATE_IE)); - if (!need_resched()) + if (!need_resched() && !cpu_is_offline(cpu)) sun4v_cpu_yield(); /* Re-enable interrupts. */ @@ -86,15 +87,25 @@ /* The idle loop on sparc64. */ void cpu_idle(void) { + int cpu = smp_processor_id(); + set_thread_flag(TIF_POLLING_NRFLAG); while(1) { tick_nohz_stop_sched_tick(); - while (!need_resched()) - sparc64_yield(); + + while (!need_resched() && !cpu_is_offline(cpu)) + sparc64_yield(cpu); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); + +#ifdef CONFIG_HOTPLUG_CPU + if (cpu_is_offline(cpu)) + cpu_play_dead(); +#endif + schedule(); preempt_disable(); } @@ -108,7 +119,7 @@ void machine_halt(void) { sstate_halt(); - if (!serial_console && prom_palette) + if (prom_palette) prom_palette (1); if (prom_keyboard) prom_keyboard(); @@ -119,7 +130,7 @@ void machine_alt_power_off(void) { sstate_poweroff(); - if (!serial_console && prom_palette) + if (prom_palette) prom_palette(1); if (prom_keyboard) prom_keyboard(); @@ -134,7 +145,7 @@ sstate_reboot(); p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (!serial_console && prom_palette) + if (prom_palette) prom_palette (1); if (prom_keyboard) prom_keyboard(); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/setup.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/setup.c @@ -133,33 +133,6 @@ } } -static void __init process_console(char *commands) -{ - serial_console = 0; - commands += 8; - /* Linux-style serial */ - if (!strncmp(commands, "ttyS", 4)) - serial_console = simple_strtoul(commands + 4, NULL, 10) + 1; - else if (!strncmp(commands, "tty", 3)) { - char c = *(commands + 3); - /* Solaris-style serial */ - if (c == 'a' || c == 'b') { - serial_console = c - 'a' + 1; - prom_printf ("Using /dev/tty%c as console.\n", c); - } - /* else Linux-style fbcon, not serial */ - } -#if defined(CONFIG_PROM_CONSOLE) - if (!strncmp(commands, "prom", 4)) { - char *p; - - for (p = commands - 8; *p && *p != ' '; p++) - *p = ' '; - conswitchp = &prom_con; - } -#endif -} - static void __init boot_flags_init(char *commands) { while (*commands) { @@ -176,9 +149,7 @@ process_switch(*commands++); continue; } - if (!strncmp(commands, "console=", 8)) { - process_console(commands); - } else if (!strncmp(commands, "mem=", 4)) { + if (!strncmp(commands, "mem=", 4)) { /* * "mem=XXX[kKmM]" overrides the PROM-reported * memory size. @@ -378,44 +349,6 @@ paging_init(); } -static int __init set_preferred_console(void) -{ - int idev, odev; - - /* The user has requested a console so this is already set up. */ - if (serial_console >= 0) - return -EBUSY; - - idev = prom_query_input_device(); - odev = prom_query_output_device(); - if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { - serial_console = 0; - } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { - serial_console = 1; - } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { - serial_console = 2; - } else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) { - serial_console = 3; - } else if (idev == PROMDEV_IVCONS && odev == PROMDEV_OVCONS) { - /* sunhv_console_init() doesn't check the serial_console - * value anyways... - */ - serial_console = 4; - return add_preferred_console("ttyHV", 0, NULL); - } else { - prom_printf("Inconsistent console: " - "input %d, output %d\n", - idev, odev); - prom_halt(); - } - - if (serial_console) - return add_preferred_console("ttyS", serial_console - 1, NULL); - - return -ENODEV; -} -console_initcall(set_preferred_console); - /* BUFFER is PAGE_SIZE bytes long. */ extern char *sparc_cpu_type; @@ -442,7 +375,6 @@ "D$ parity tl1\t: %u\n" "I$ parity tl1\t: %u\n" #ifndef CONFIG_SMP - "Cpu0Bogo\t: %lu.%02lu\n" "Cpu0ClkTck\t: %016lx\n" #endif , @@ -457,9 +389,7 @@ dcache_parity_tl1_occurred, icache_parity_tl1_occurred #ifndef CONFIG_SMP - , cpu_data(0).udelay_val/(500000/HZ), - (cpu_data(0).udelay_val/(5000/HZ)) % 100, - cpu_data(0).clock_tick + , cpu_data(0).clock_tick #endif ); #ifdef CONFIG_SMP @@ -511,5 +441,4 @@ prom_cmdline(); } -int serial_console = -1; int stop_a_enabled = 1; --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/pci.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/pci.c @@ -404,7 +404,6 @@ sd->host_controller = pbm; sd->prom_node = node; sd->op = of_find_device_by_node(node); - sd->msi_num = 0xffffffff; type = of_get_property(node, "device_type", NULL); if (type == NULL) @@ -422,10 +421,15 @@ dev->multifunction = 0; /* maybe a lie? */ if (host_controller) { - dev->vendor = 0x108e; - dev->device = 0x8000; - dev->subsystem_vendor = 0x0000; - dev->subsystem_device = 0x0000; + if (tlb_type != hypervisor) { + pci_read_config_word(dev, PCI_VENDOR_ID, + &dev->vendor); + pci_read_config_word(dev, PCI_DEVICE_ID, + &dev->device); + } else { + dev->vendor = PCI_VENDOR_ID_SUN; + dev->device = 0x80f0; + } dev->cfg_size = 256; dev->class = PCI_CLASS_BRIDGE_HOST << 8; sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), @@ -746,7 +750,7 @@ { struct device_node *child; const u32 *reg; - int reglen, devfn; + int reglen, devfn, prev_devfn; struct pci_dev *dev; if (ofpci_verbose) @@ -754,14 +758,25 @@ node->full_name, bus->number); child = NULL; + prev_devfn = -1; while ((child = of_get_next_child(node, child)) != NULL) { if (ofpci_verbose) printk(" * %s\n", child->full_name); reg = of_get_property(child, "reg", ®len); if (reg == NULL || reglen < 20) continue; + devfn = (reg[0] >> 8) & 0xff; + /* This is a workaround for some device trees + * which list PCI devices twice. On the V100 + * for example, device number 3 is listed twice. + * Once as "pm" and once again as "lomp". + */ + if (devfn == prev_devfn) + continue; + prev_devfn = devfn; + /* create a new pci_dev for this device */ dev = of_create_pci_dev(pbm, child, bus, devfn, 0); if (!dev) @@ -817,7 +832,7 @@ { static u8 fake_pci_config[] = { 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ - 0x00, 0x80, /* Device: 0x8000 (PBM) */ + 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/irq.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/irq.c @@ -87,7 +87,11 @@ */ #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) -static unsigned int virt_to_real_irq_table[NR_IRQS]; +static struct { + unsigned int irq; + unsigned int dev_handle; + unsigned int dev_ino; +} virt_to_real_irq_table[NR_IRQS]; static unsigned char virt_irq_alloc(unsigned int real_irq) { @@ -96,7 +100,7 @@ BUILD_BUG_ON(NR_IRQS >= 256); for (ent = 1; ent < NR_IRQS; ent++) { - if (!virt_to_real_irq_table[ent]) + if (!virt_to_real_irq_table[ent].irq) break; } if (ent >= NR_IRQS) { @@ -104,7 +108,7 @@ return 0; } - virt_to_real_irq_table[ent] = real_irq; + virt_to_real_irq_table[ent].irq = real_irq; return ent; } @@ -117,8 +121,8 @@ if (virt_irq >= NR_IRQS) return; - real_irq = virt_to_real_irq_table[virt_irq]; - virt_to_real_irq_table[virt_irq] = 0; + real_irq = virt_to_real_irq_table[virt_irq].irq; + virt_to_real_irq_table[virt_irq].irq = 0; __bucket(real_irq)->virt_irq = 0; } @@ -126,7 +130,7 @@ static unsigned int virt_to_real_irq(unsigned char virt_irq) { - return virt_to_real_irq_table[virt_irq]; + return virt_to_real_irq_table[virt_irq].irq; } /* @@ -213,8 +217,27 @@ void (*pre_handler)(unsigned int, void *, void *); void *pre_handler_arg1; void *pre_handler_arg2; + + u32 msi; }; +void sparc64_set_msi(unsigned int virt_irq, u32 msi) +{ + struct irq_handler_data *data = get_irq_chip_data(virt_irq); + + if (data) + data->msi = msi; +} + +u32 sparc64_get_msi(unsigned int virt_irq) +{ + struct irq_handler_data *data = get_irq_chip_data(virt_irq); + + if (data) + return data->msi; + return 0xffffffff; +} + static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) { unsigned int real_irq = virt_to_real_irq(virt_irq); @@ -293,13 +316,18 @@ } } +static void sun4u_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + sun4u_irq_enable(virt_irq); +} + static void sun4u_irq_disable(unsigned int virt_irq) { struct irq_handler_data *data = get_irq_chip_data(virt_irq); if (likely(data)) { unsigned long imap = data->imap; - u32 tmp = upa_readq(imap); + unsigned long tmp = upa_readq(imap); tmp &= ~IMAP_VALID; upa_writeq(tmp, imap); @@ -327,19 +355,37 @@ err = sun4v_intr_settarget(ino, cpuid); if (err != HV_EOK) - printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", - ino, cpuid, err); + printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " + "err(%d)\n", ino, cpuid, err); err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk("sun4v_intr_setstate(%x): " + printk(KERN_ERR "sun4v_intr_setstate(%x): " "err(%d)\n", ino, err); err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); if (err != HV_EOK) - printk("sun4v_intr_setenabled(%x): err(%d)\n", + printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n", ino, err); } } +static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long cpuid; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + err = sun4v_intr_settarget(ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): " + "err(%d)\n", ino, cpuid, err); + } +} + static void sun4v_irq_disable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); @@ -350,12 +396,24 @@ err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); if (err != HV_EOK) - printk("sun4v_intr_setenabled(%x): " + printk(KERN_ERR "sun4v_intr_setenabled(%x): " "err(%d)\n", ino, err); } } #ifdef CONFIG_PCI_MSI +static void sun4u_msi_enable(unsigned int virt_irq) +{ + sun4u_irq_enable(virt_irq); + unmask_msi_irq(virt_irq); +} + +static void sun4u_msi_disable(unsigned int virt_irq) +{ + mask_msi_irq(virt_irq); + sun4u_irq_disable(virt_irq); +} + static void sun4v_msi_enable(unsigned int virt_irq) { sun4v_irq_enable(virt_irq); @@ -379,7 +437,7 @@ err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk("sun4v_intr_setstate(%x): " + printk(KERN_ERR "sun4v_intr_setstate(%x): " "err(%d)\n", ino, err); } } @@ -387,7 +445,6 @@ static void sun4v_virq_enable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - unsigned int ino = bucket - &ivector_table[0]; if (likely(bucket)) { unsigned long cpuid, dev_handle, dev_ino; @@ -395,45 +452,65 @@ cpuid = irq_choose_cpu(virt_irq); - dev_handle = ino & IMAP_IGN; - dev_ino = ino & IMAP_INO; + dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; + dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) - printk("sun4v_vintr_set_target(%lx,%lx,%lu): " + printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " "err(%d)\n", dev_handle, dev_ino, cpuid, err); err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk("sun4v_vintr_set_state(%lx,%lx," + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," "HV_INTR_STATE_IDLE): err(%d)\n", dev_handle, dev_ino, err); err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_ENABLED); if (err != HV_EOK) - printk("sun4v_vintr_set_state(%lx,%lx," + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," "HV_INTR_ENABLED): err(%d)\n", dev_handle, dev_ino, err); } } +static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + + if (likely(bucket)) { + unsigned long cpuid, dev_handle, dev_ino; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; + dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; + + err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); + if (err != HV_EOK) + printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): " + "err(%d)\n", + dev_handle, dev_ino, cpuid, err); + } +} + static void sun4v_virq_disable(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - unsigned int ino = bucket - &ivector_table[0]; if (likely(bucket)) { unsigned long dev_handle, dev_ino; int err; - dev_handle = ino & IMAP_IGN; - dev_ino = ino & IMAP_INO; + dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; + dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_DISABLED); if (err != HV_EOK) - printk("sun4v_vintr_set_state(%lx,%lx," + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," "HV_INTR_DISABLED): err(%d)\n", dev_handle, dev_ino, err); } @@ -442,20 +519,21 @@ static void sun4v_virq_end(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - unsigned int ino = bucket - &ivector_table[0]; + struct irq_desc *desc = irq_desc + virt_irq; - if (likely(bucket)) { + if (likely(bucket && + !(desc->status & IRQ_INPROGRESS))) { unsigned long dev_handle, dev_ino; int err; - dev_handle = ino & IMAP_IGN; - dev_ino = ino & IMAP_INO; + dev_handle = virt_to_real_irq_table[virt_irq].dev_handle; + dev_ino = virt_to_real_irq_table[virt_irq].dev_ino; err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); if (err != HV_EOK) - printk("sun4v_vintr_set_state(%lx,%lx," - "HV_INTR_STATE_IDLE): err(%d)\n", + printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_STATE_IDLE): err(%d)\n", dev_handle, dev_ino, err); } } @@ -477,6 +555,7 @@ .enable = sun4u_irq_enable, .disable = sun4u_irq_disable, .end = sun4u_irq_end, + .set_affinity = sun4u_set_affinity, }; static struct irq_chip sun4u_irq_ack = { @@ -485,6 +564,7 @@ .disable = sun4u_irq_disable, .ack = run_pre_handler, .end = sun4u_irq_end, + .set_affinity = sun4u_set_affinity, }; static struct irq_chip sun4v_irq = { @@ -492,6 +572,7 @@ .enable = sun4v_irq_enable, .disable = sun4v_irq_disable, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; static struct irq_chip sun4v_irq_ack = { @@ -500,9 +581,21 @@ .disable = sun4v_irq_disable, .ack = run_pre_handler, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; #ifdef CONFIG_PCI_MSI +static struct irq_chip sun4u_msi = { + .typename = "sun4u+msi", + .mask = mask_msi_irq, + .unmask = unmask_msi_irq, + .enable = sun4u_msi_enable, + .disable = sun4u_msi_disable, + .ack = run_pre_handler, + .end = sun4u_irq_end, + .set_affinity = sun4u_set_affinity, +}; + static struct irq_chip sun4v_msi = { .typename = "sun4v+msi", .mask = mask_msi_irq, @@ -511,6 +604,7 @@ .disable = sun4v_msi_disable, .ack = run_pre_handler, .end = sun4v_irq_end, + .set_affinity = sun4v_set_affinity, }; #endif @@ -519,6 +613,7 @@ .enable = sun4v_virq_enable, .disable = sun4v_virq_disable, .end = sun4v_virq_end, + .set_affinity = sun4v_virt_set_affinity, }; static struct irq_chip sun4v_virq_ack = { @@ -527,6 +622,7 @@ .disable = sun4v_virq_disable, .ack = run_pre_handler, .end = sun4v_virq_end, + .set_affinity = sun4v_virt_set_affinity, }; void irq_install_pre_handler(int virt_irq, @@ -545,6 +641,7 @@ chip == &sun4v_irq_ack || chip == &sun4v_virq_ack #ifdef CONFIG_PCI_MSI + || chip == &sun4u_msi || chip == &sun4v_msi #endif ) @@ -636,11 +733,12 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { unsigned long sysino, hv_err; + unsigned int virq; - BUG_ON(devhandle & ~IMAP_IGN); - BUG_ON(devino & ~IMAP_INO); + BUG_ON(devhandle & devino); sysino = devhandle | devino; + BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); if (hv_err) { @@ -649,7 +747,12 @@ prom_halt(); } - return sun4v_build_common(sysino, &sun4v_virq); + virq = sun4v_build_common(sysino, &sun4v_virq); + + virt_to_real_irq_table[virq].dev_handle = devhandle; + virt_to_real_irq_table[virq].dev_ino = devino; + + return virq; } #ifdef CONFIG_PCI_MSI @@ -671,7 +774,7 @@ break; } if (devino >= msi_end) - return 0; + return -ENOSPC; sysino = sun4v_devino_to_sysino(devhandle, devino); bucket = &ivector_table[sysino]; @@ -685,8 +788,8 @@ data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); if (unlikely(!data)) { - prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); - prom_halt(); + virt_irq_free(*virt_irq_p); + return -ENOMEM; } set_irq_chip_data(bucket->virt_irq, data); @@ -700,6 +803,53 @@ { virt_irq_free(virt_irq); } + +unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p, + unsigned int msi_start, unsigned int msi_end, + unsigned long imap_base, unsigned long iclr_base) +{ + struct ino_bucket *bucket; + struct irq_handler_data *data; + unsigned long sysino; + unsigned int devino; + + /* Find a free devino in the given range. */ + for (devino = msi_start; devino < msi_end; devino++) { + sysino = (portid << 6) | devino; + bucket = &ivector_table[sysino]; + if (!bucket->virt_irq) + break; + } + if (devino >= msi_end) + return -ENOSPC; + + sysino = (portid << 6) | devino; + bucket = &ivector_table[sysino]; + bucket->virt_irq = virt_irq_alloc(__irq(bucket)); + *virt_irq_p = bucket->virt_irq; + set_irq_chip(bucket->virt_irq, &sun4u_msi); + + data = get_irq_chip_data(bucket->virt_irq); + if (unlikely(data)) + return devino; + + data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + if (unlikely(!data)) { + virt_irq_free(*virt_irq_p); + return -ENOMEM; + } + set_irq_chip_data(bucket->virt_irq, data); + + data->imap = (imap_base + (devino * 0x8UL)); + data->iclr = (iclr_base + (devino * 0x8UL)); + + return devino; +} + +void sun4u_destroy_msi(unsigned int virt_irq) +{ + virt_irq_free(virt_irq); +} #endif void ack_bad_irq(unsigned int virt_irq) @@ -739,6 +889,26 @@ set_irq_regs(old_regs); } +#ifdef CONFIG_HOTPLUG_CPU +void fixup_irqs(void) +{ + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; irq++) { + unsigned long flags; + + spin_lock_irqsave(&irq_desc[irq].lock, flags); + if (irq_desc[irq].action && + !(irq_desc[irq].status & IRQ_PER_CPU)) { + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, + irq_desc[irq].affinity); + } + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + } +} +#endif + struct sun5_timer { u64 count0; u64 limit0; @@ -839,7 +1009,7 @@ } } -static void __cpuinit sun4v_register_mondo_queues(int this_cpu) +void __cpuinit sun4v_register_mondo_queues(int this_cpu) { struct trap_per_cpu *tb = &trap_block[this_cpu]; @@ -853,20 +1023,10 @@ tb->nonresum_qmask); } -static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) +static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - unsigned long order = get_order(size); - void *p = NULL; - - if (use_bootmem) { - p = __alloc_bootmem_low(size, size, 0); - } else { - struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order); - if (page) - p = page_address(page); - } - + void *p = __alloc_bootmem(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); prom_halt(); @@ -875,19 +1035,10 @@ *pa_ptr = __pa(p); } -static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) +static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - unsigned long order = get_order(size); - void *p = NULL; - - if (use_bootmem) { - p = __alloc_bootmem_low(size, size, 0); - } else { - struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order); - if (page) - p = page_address(page); - } + void *p = __alloc_bootmem(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); @@ -897,18 +1048,14 @@ *pa_ptr = __pa(p); } -static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) +static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) { #ifdef CONFIG_SMP void *page; BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); - if (use_bootmem) - page = alloc_bootmem_low_pages(PAGE_SIZE); - else - page = (void *) get_zeroed_page(GFP_ATOMIC); - + page = alloc_bootmem_pages(PAGE_SIZE); if (!page) { prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); prom_halt(); @@ -919,30 +1066,27 @@ #endif } -/* Allocate and register the mondo and error queues for this cpu. */ -void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load) +/* Allocate mondo and error queues for all possible cpus. */ +static void __init sun4v_init_mondo_queues(void) { - struct trap_per_cpu *tb = &trap_block[cpu]; + int cpu; - if (alloc) { - alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem); - alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem); - alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem); - alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem); - alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem); - alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem); - - init_cpu_send_mondo_info(tb, use_bootmem); - } - - if (load) { - if (cpu != hard_smp_processor_id()) { - prom_printf("SUN4V: init mondo on cpu %d not %d\n", - cpu, hard_smp_processor_id()); - prom_halt(); - } - sun4v_register_mondo_queues(cpu); + for_each_possible_cpu(cpu) { + struct trap_per_cpu *tb = &trap_block[cpu]; + + alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); + alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask); + alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask); + alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask); + alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask); + alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, + tb->nonresum_qmask); + + init_cpu_send_mondo_info(tb); } + + /* Load up the boot cpu's entries. */ + sun4v_register_mondo_queues(hard_smp_processor_id()); } static struct irqaction timer_irq_action = { @@ -957,7 +1101,7 @@ memset(&ivector_table[0], 0, sizeof(ivector_table)); if (tlb_type == hypervisor) - sun4v_init_mondo_queues(1, hard_smp_processor_id(), 1, 1); + sun4v_init_mondo_queues(); /* We need to clear any IRQ's pending in the soft interrupt * registers, a spurious one could be left around from the --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/cpu.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/cpu.c @@ -1,7 +1,7 @@ /* cpu.c: Dinky routines to look for the kind of Sparc cpu * we are on. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -13,6 +13,7 @@ #include #include #include +#include DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; @@ -61,21 +62,40 @@ #define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips) -char *sparc_cpu_type = "cpu-oops"; -char *sparc_fpu_type = "fpu-oops"; +char *sparc_cpu_type; +char *sparc_fpu_type; unsigned int fsr_storage; +static void __init sun4v_cpu_probe(void) +{ + switch (sun4v_chip_type) { + case SUN4V_CHIP_NIAGARA1: + sparc_cpu_type = "UltraSparc T1 (Niagara)"; + sparc_fpu_type = "UltraSparc T1 integrated FPU"; + break; + + case SUN4V_CHIP_NIAGARA2: + sparc_cpu_type = "UltraSparc T2 (Niagara2)"; + sparc_fpu_type = "UltraSparc T2 integrated FPU"; + break; + + default: + printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", + prom_cpu_compatible); + sparc_cpu_type = "Unknown SUN4V CPU"; + sparc_fpu_type = "Unknown SUN4V FPU"; + break; + } +} + void __init cpu_probe(void) { unsigned long ver, fpu_vers, manuf, impl, fprs; int i; - if (tlb_type == hypervisor) { - sparc_cpu_type = "UltraSparc T1 (Niagara)"; - sparc_fpu_type = "UltraSparc T1 integrated FPU"; - return; - } + if (tlb_type == hypervisor) + return sun4v_cpu_probe(); fprs = fprs_read(); fprs_write(FPRS_FEF); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/sparc64_ksyms.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,7 +1,6 @@ -/* $Id: sparc64_ksyms.c,v 1.121 2002/02/09 19:49:31 davem Exp $ - * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. +/* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) */ @@ -28,7 +27,6 @@ #include #include -#include #include #include #include @@ -124,10 +122,6 @@ EXPORT_SYMBOL(__write_unlock); EXPORT_SYMBOL(__write_trylock); -/* CPU online map and active count. */ -EXPORT_SYMBOL(cpu_online_map); -EXPORT_SYMBOL(phys_cpu_present_map); - EXPORT_SYMBOL(smp_call_function); #endif /* CONFIG_SMP */ @@ -174,6 +168,7 @@ EXPORT_SYMBOL(__flushw_user); EXPORT_SYMBOL(tlb_type); +EXPORT_SYMBOL(sun4v_chip_type); EXPORT_SYMBOL(get_fb_unmapped_area); EXPORT_SYMBOL(flush_icache_range); @@ -330,19 +325,12 @@ EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(strncmp); -/* Delay routines. */ -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__ndelay); -EXPORT_SYMBOL(__const_udelay); -EXPORT_SYMBOL(__delay); - void VISenter(void); /* RAID code needs this */ EXPORT_SYMBOL(VISenter); /* for input/keybdev */ EXPORT_SYMBOL(sun_do_break); -EXPORT_SYMBOL(serial_console); EXPORT_SYMBOL(stop_a_enabled); #ifdef CONFIG_DEBUG_BUGVERBOSE --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/traps.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/traps.c @@ -2134,12 +2134,20 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) { unsigned long pc, fp, thread_base, ksp; - void *tp = task_stack_page(tsk); + struct thread_info *tp; struct reg_window *rw; int count = 0; ksp = (unsigned long) _ksp; - + if (!tsk) + tsk = current; + tp = task_thread_info(tsk); + if (ksp == 0UL) { + if (tsk == current) + asm("mov %%fp, %0" : "=r" (ksp)); + else + ksp = tp->ksp; + } if (tp == current_thread_info()) flushw_all(); @@ -2168,11 +2176,7 @@ void dump_stack(void) { - unsigned long *ksp; - - __asm__ __volatile__("mov %%fp, %0" - : "=r" (ksp)); - show_stack(current, ksp); + show_stack(current, NULL); } EXPORT_SYMBOL(dump_stack); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/trampoline.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/trampoline.S @@ -95,14 +95,13 @@ membar #Sync startup_continue: + mov %o0, %l0 + BRANCH_IF_SUN4V(g1, niagara_lock_tlb) + sethi %hi(0x80000000), %g2 sllx %g2, 32, %g2 wr %g2, 0, %tick_cmpr - mov %o0, %l0 - - BRANCH_IF_SUN4V(g1, niagara_lock_tlb) - /* Call OBP by hand to lock KERNBASE into i/d tlbs. * We lock 2 consequetive entries if we are 'bigkernel'. */ @@ -346,7 +345,7 @@ sethi %hi(tramp_stack), %g1 or %g1, %lo(tramp_stack), %g1 add %g1, TRAMP_STACK_SIZE, %g1 - sub %g1, STACKFRAME_SZ + STACK_BIAS, %sp + sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp mov 0, %fp /* Put garbage in these registers to trap any access to them. */ @@ -366,11 +365,8 @@ call hard_smp_processor_id nop - mov %o0, %o1 - mov 0, %o0 - mov 0, %o2 - call sun4v_init_mondo_queues - mov 1, %o3 + call sun4v_register_mondo_queues + nop 1: call init_cur_cpu_trap ldx [%l0], %o0 @@ -415,15 +411,38 @@ sethi %hi(kern_base), %g3 ldx [%g3 + %lo(kern_base)], %g3 add %g2, %g3, %o1 + sethi %hi(sparc64_ttable_tl0), %o0 - call prom_set_trap_table_sun4v - sethi %hi(sparc64_ttable_tl0), %o0 + set prom_set_trap_table_name, %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 2, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 0, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + stx %o0, [%sp + 2047 + 128 + 0x18] + stx %o1, [%sp + 2047 + 128 + 0x20] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 ba,pt %xcc, 2f nop -1: call prom_set_trap_table - sethi %hi(sparc64_ttable_tl0), %o0 +1: sethi %hi(sparc64_ttable_tl0), %o0 + set prom_set_trap_table_name, %g2 + stx %g2, [%sp + 2047 + 128 + 0x00] + mov 1, %g2 + stx %g2, [%sp + 2047 + 128 + 0x08] + mov 0, %g2 + stx %g2, [%sp + 2047 + 128 + 0x10] + stx %o0, [%sp + 2047 + 128 + 0x18] + sethi %hi(p1275buf), %g2 + or %g2, %lo(p1275buf), %g2 + ldx [%g2 + 0x08], %o1 + call %o1 + add %sp, (2047 + 128), %o0 2: ldx [%l0], %g6 ldx [%g6 + TI_TASK], %g4 --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/power.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/power.c @@ -1,7 +1,6 @@ -/* $Id: power.c,v 1.10 2001/12/11 01:57:16 davem Exp $ - * power.c: Power management driver. +/* power.c: Power management driver. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include @@ -29,24 +29,26 @@ */ int scons_pwroff = 1; -#ifdef CONFIG_PCI -#include static void __iomem *power_reg; static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); static int button_pressed; -static irqreturn_t power_handler(int irq, void *dev_id) +void wake_up_powerd(void) { if (button_pressed == 0) { button_pressed = 1; wake_up(&powerd_wait); } +} + +static irqreturn_t power_handler(int irq, void *dev_id) +{ + wake_up_powerd(); /* FIXME: Check registers for status... */ return IRQ_HANDLED; } -#endif /* CONFIG_PCI */ extern void machine_halt(void); extern void machine_alt_power_off(void); @@ -55,20 +57,19 @@ void machine_power_off(void) { sstate_poweroff(); - if (!serial_console || scons_pwroff) { -#ifdef CONFIG_PCI + if (strcmp(of_console_device->type, "serial") || scons_pwroff) { if (power_reg) { /* Both register bits seem to have the * same effect, so until I figure out * what the difference is... */ writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg); - } else -#endif /* CONFIG_PCI */ + } else { if (poweroff_method != NULL) { poweroff_method(); /* not reached */ } + } } machine_halt(); } @@ -76,7 +77,6 @@ void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); -#ifdef CONFIG_PCI static int powerd(void *__unused) { static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; @@ -86,7 +86,7 @@ daemonize("powerd"); add_wait_queue(&powerd_wait, &wait); -again: + for (;;) { set_task_state(current, TASK_INTERRUPTIBLE); if (button_pressed) @@ -100,16 +100,28 @@ /* Ok, down we go... */ button_pressed = 0; if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { - printk("powerd: shutdown execution failed\n"); - add_wait_queue(&powerd_wait, &wait); - goto again; + printk(KERN_ERR "powerd: shutdown execution failed\n"); + machine_power_off(); } return 0; } +int start_powerd(void) +{ + int err; + + err = kernel_thread(powerd, NULL, CLONE_FS); + if (err < 0) + printk(KERN_ERR "power: Failed to start power daemon.\n"); + else + printk(KERN_INFO "power: powerd running.\n"); + + return err; +} + static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) { - if (irq == PCI_IRQ_NONE) + if (irq == 0xffffffff) return 0; if (!of_find_property(dp, "button", NULL)) return 0; @@ -130,17 +142,14 @@ poweroff_method = machine_halt; /* able to use the standard halt */ if (has_button_interrupt(irq, op->node)) { - if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { - printk("Failed to start power daemon.\n"); + if (start_powerd() < 0) return 0; - } - printk("powerd running.\n"); if (request_irq(irq, power_handler, 0, "power", NULL) < 0) - printk("power: Error, cannot register IRQ handler.\n"); + printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); } else { - printk("not using powerd.\n"); + printk(KERN_INFO "power: Not using powerd.\n"); } return 0; @@ -164,4 +173,3 @@ of_register_driver(&power_driver, &of_bus_type); return; } -#endif /* CONFIG_PCI */ --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/ldc.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/ldc.c @@ -0,0 +1,2373 @@ +/* ldc.c: Logical Domain Channel link-layer protocol driver. + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DRV_MODULE_NAME "ldc" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "June 25, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +#define LDC_PACKET_SIZE 64 + +/* Packet header layout for unreliable and reliable mode frames. + * When in RAW mode, packets are simply straight 64-byte payloads + * with no headers. + */ +struct ldc_packet { + u8 type; +#define LDC_CTRL 0x01 +#define LDC_DATA 0x02 +#define LDC_ERR 0x10 + + u8 stype; +#define LDC_INFO 0x01 +#define LDC_ACK 0x02 +#define LDC_NACK 0x04 + + u8 ctrl; +#define LDC_VERS 0x01 /* Link Version */ +#define LDC_RTS 0x02 /* Request To Send */ +#define LDC_RTR 0x03 /* Ready To Receive */ +#define LDC_RDX 0x04 /* Ready for Data eXchange */ +#define LDC_CTRL_MSK 0x0f + + u8 env; +#define LDC_LEN 0x3f +#define LDC_FRAG_MASK 0xc0 +#define LDC_START 0x40 +#define LDC_STOP 0x80 + + u32 seqid; + + union { + u8 u_data[LDC_PACKET_SIZE - 8]; + struct { + u32 pad; + u32 ackid; + u8 r_data[LDC_PACKET_SIZE - 8 - 8]; + } r; + } u; +}; + +struct ldc_version { + u16 major; + u16 minor; +}; + +/* Ordered from largest major to lowest. */ +static struct ldc_version ver_arr[] = { + { .major = 1, .minor = 0 }, +}; + +#define LDC_DEFAULT_MTU (4 * LDC_PACKET_SIZE) +#define LDC_DEFAULT_NUM_ENTRIES (PAGE_SIZE / LDC_PACKET_SIZE) + +struct ldc_channel; + +struct ldc_mode_ops { + int (*write)(struct ldc_channel *, const void *, unsigned int); + int (*read)(struct ldc_channel *, void *, unsigned int); +}; + +static const struct ldc_mode_ops raw_ops; +static const struct ldc_mode_ops nonraw_ops; +static const struct ldc_mode_ops stream_ops; + +int ldom_domaining_enabled; + +struct ldc_iommu { + /* Protects arena alloc/free. */ + spinlock_t lock; + struct iommu_arena arena; + struct ldc_mtable_entry *page_table; +}; + +struct ldc_channel { + /* Protects all operations that depend upon channel state. */ + spinlock_t lock; + + unsigned long id; + + u8 *mssbuf; + u32 mssbuf_len; + u32 mssbuf_off; + + struct ldc_packet *tx_base; + unsigned long tx_head; + unsigned long tx_tail; + unsigned long tx_num_entries; + unsigned long tx_ra; + + unsigned long tx_acked; + + struct ldc_packet *rx_base; + unsigned long rx_head; + unsigned long rx_tail; + unsigned long rx_num_entries; + unsigned long rx_ra; + + u32 rcv_nxt; + u32 snd_nxt; + + unsigned long chan_state; + + struct ldc_channel_config cfg; + void *event_arg; + + const struct ldc_mode_ops *mops; + + struct ldc_iommu iommu; + + struct ldc_version ver; + + u8 hs_state; +#define LDC_HS_CLOSED 0x00 +#define LDC_HS_OPEN 0x01 +#define LDC_HS_GOTVERS 0x02 +#define LDC_HS_SENTRTR 0x03 +#define LDC_HS_GOTRTR 0x04 +#define LDC_HS_COMPLETE 0x10 + + u8 flags; +#define LDC_FLAG_ALLOCED_QUEUES 0x01 +#define LDC_FLAG_REGISTERED_QUEUES 0x02 +#define LDC_FLAG_REGISTERED_IRQS 0x04 +#define LDC_FLAG_RESET 0x10 + + u8 mss; + u8 state; + +#define LDC_IRQ_NAME_MAX 32 + char rx_irq_name[LDC_IRQ_NAME_MAX]; + char tx_irq_name[LDC_IRQ_NAME_MAX]; + + struct hlist_head mh_list; + + struct hlist_node list; +}; + +#define ldcdbg(TYPE, f, a...) \ +do { if (lp->cfg.debug & LDC_DEBUG_##TYPE) \ + printk(KERN_INFO PFX "ID[%lu] " f, lp->id, ## a); \ +} while (0) + +static const char *state_to_str(u8 state) +{ + switch (state) { + case LDC_STATE_INVALID: + return "INVALID"; + case LDC_STATE_INIT: + return "INIT"; + case LDC_STATE_BOUND: + return "BOUND"; + case LDC_STATE_READY: + return "READY"; + case LDC_STATE_CONNECTED: + return "CONNECTED"; + default: + return ""; + } +} + +static void ldc_set_state(struct ldc_channel *lp, u8 state) +{ + ldcdbg(STATE, "STATE (%s) --> (%s)\n", + state_to_str(lp->state), + state_to_str(state)); + + lp->state = state; +} + +static unsigned long __advance(unsigned long off, unsigned long num_entries) +{ + off += LDC_PACKET_SIZE; + if (off == (num_entries * LDC_PACKET_SIZE)) + off = 0; + + return off; +} + +static unsigned long rx_advance(struct ldc_channel *lp, unsigned long off) +{ + return __advance(off, lp->rx_num_entries); +} + +static unsigned long tx_advance(struct ldc_channel *lp, unsigned long off) +{ + return __advance(off, lp->tx_num_entries); +} + +static struct ldc_packet *handshake_get_tx_packet(struct ldc_channel *lp, + unsigned long *new_tail) +{ + struct ldc_packet *p; + unsigned long t; + + t = tx_advance(lp, lp->tx_tail); + if (t == lp->tx_head) + return NULL; + + *new_tail = t; + + p = lp->tx_base; + return p + (lp->tx_tail / LDC_PACKET_SIZE); +} + +/* When we are in reliable or stream mode, have to track the next packet + * we haven't gotten an ACK for in the TX queue using tx_acked. We have + * to be careful not to stomp over the queue past that point. During + * the handshake, we don't have TX data packets pending in the queue + * and that's why handshake_get_tx_packet() need not be mindful of + * lp->tx_acked. + */ +static unsigned long head_for_data(struct ldc_channel *lp) +{ + if (lp->cfg.mode == LDC_MODE_STREAM) + return lp->tx_acked; + return lp->tx_head; +} + +static int tx_has_space_for(struct ldc_channel *lp, unsigned int size) +{ + unsigned long limit, tail, new_tail, diff; + unsigned int mss; + + limit = head_for_data(lp); + tail = lp->tx_tail; + new_tail = tx_advance(lp, tail); + if (new_tail == limit) + return 0; + + if (limit > new_tail) + diff = limit - new_tail; + else + diff = (limit + + ((lp->tx_num_entries * LDC_PACKET_SIZE) - new_tail)); + diff /= LDC_PACKET_SIZE; + mss = lp->mss; + + if (diff * mss < size) + return 0; + + return 1; +} + +static struct ldc_packet *data_get_tx_packet(struct ldc_channel *lp, + unsigned long *new_tail) +{ + struct ldc_packet *p; + unsigned long h, t; + + h = head_for_data(lp); + t = tx_advance(lp, lp->tx_tail); + if (t == h) + return NULL; + + *new_tail = t; + + p = lp->tx_base; + return p + (lp->tx_tail / LDC_PACKET_SIZE); +} + +static int set_tx_tail(struct ldc_channel *lp, unsigned long tail) +{ + unsigned long orig_tail = lp->tx_tail; + int limit = 1000; + + lp->tx_tail = tail; + while (limit-- > 0) { + unsigned long err; + + err = sun4v_ldc_tx_set_qtail(lp->id, tail); + if (!err) + return 0; + + if (err != HV_EWOULDBLOCK) { + lp->tx_tail = orig_tail; + return -EINVAL; + } + udelay(1); + } + + lp->tx_tail = orig_tail; + return -EBUSY; +} + +/* This just updates the head value in the hypervisor using + * a polling loop with a timeout. The caller takes care of + * upating software state representing the head change, if any. + */ +static int __set_rx_head(struct ldc_channel *lp, unsigned long head) +{ + int limit = 1000; + + while (limit-- > 0) { + unsigned long err; + + err = sun4v_ldc_rx_set_qhead(lp->id, head); + if (!err) + return 0; + + if (err != HV_EWOULDBLOCK) + return -EINVAL; + + udelay(1); + } + + return -EBUSY; +} + +static int send_tx_packet(struct ldc_channel *lp, + struct ldc_packet *p, + unsigned long new_tail) +{ + BUG_ON(p != (lp->tx_base + (lp->tx_tail / LDC_PACKET_SIZE))); + + return set_tx_tail(lp, new_tail); +} + +static struct ldc_packet *handshake_compose_ctrl(struct ldc_channel *lp, + u8 stype, u8 ctrl, + void *data, int dlen, + unsigned long *new_tail) +{ + struct ldc_packet *p = handshake_get_tx_packet(lp, new_tail); + + if (p) { + memset(p, 0, sizeof(*p)); + p->type = LDC_CTRL; + p->stype = stype; + p->ctrl = ctrl; + if (data) + memcpy(p->u.u_data, data, dlen); + } + return p; +} + +static int start_handshake(struct ldc_channel *lp) +{ + struct ldc_packet *p; + struct ldc_version *ver; + unsigned long new_tail; + + ver = &ver_arr[0]; + + ldcdbg(HS, "SEND VER INFO maj[%u] min[%u]\n", + ver->major, ver->minor); + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_VERS, + ver, sizeof(*ver), &new_tail); + if (p) { + int err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->flags &= ~LDC_FLAG_RESET; + return err; + } + return -EBUSY; +} + +static int send_version_nack(struct ldc_channel *lp, + u16 major, u16 minor) +{ + struct ldc_packet *p; + struct ldc_version ver; + unsigned long new_tail; + + ver.major = major; + ver.minor = minor; + + p = handshake_compose_ctrl(lp, LDC_NACK, LDC_VERS, + &ver, sizeof(ver), &new_tail); + if (p) { + ldcdbg(HS, "SEND VER NACK maj[%u] min[%u]\n", + ver.major, ver.minor); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_version_ack(struct ldc_channel *lp, + struct ldc_version *vp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_ACK, LDC_VERS, + vp, sizeof(*vp), &new_tail); + if (p) { + ldcdbg(HS, "SEND VER ACK maj[%u] min[%u]\n", + vp->major, vp->minor); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rts(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RTS, NULL, 0, + &new_tail); + if (p) { + p->env = lp->cfg.mode; + p->seqid = 0; + lp->rcv_nxt = 0; + + ldcdbg(HS, "SEND RTS env[0x%x] seqid[0x%x]\n", + p->env, p->seqid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rtr(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RTR, NULL, 0, + &new_tail); + if (p) { + p->env = lp->cfg.mode; + p->seqid = 0; + + ldcdbg(HS, "SEND RTR env[0x%x] seqid[0x%x]\n", + p->env, p->seqid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_rdx(struct ldc_channel *lp) +{ + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_RDX, NULL, 0, + &new_tail); + if (p) { + p->env = 0; + p->seqid = ++lp->snd_nxt; + p->u.r.ackid = lp->rcv_nxt; + + ldcdbg(HS, "SEND RDX env[0x%x] seqid[0x%x] ackid[0x%x]\n", + p->env, p->seqid, p->u.r.ackid); + + return send_tx_packet(lp, p, new_tail); + } + return -EBUSY; +} + +static int send_data_nack(struct ldc_channel *lp, struct ldc_packet *data_pkt) +{ + struct ldc_packet *p; + unsigned long new_tail; + int err; + + p = data_get_tx_packet(lp, &new_tail); + if (!p) + return -EBUSY; + memset(p, 0, sizeof(*p)); + p->type = data_pkt->type; + p->stype = LDC_NACK; + p->ctrl = data_pkt->ctrl & LDC_CTRL_MSK; + p->seqid = lp->snd_nxt + 1; + p->u.r.ackid = lp->rcv_nxt; + + ldcdbg(HS, "SEND DATA NACK type[0x%x] ctl[0x%x] seq[0x%x] ack[0x%x]\n", + p->type, p->ctrl, p->seqid, p->u.r.ackid); + + err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->snd_nxt++; + + return err; +} + +static int ldc_abort(struct ldc_channel *lp) +{ + unsigned long hv_err; + + ldcdbg(STATE, "ABORT\n"); + + /* We report but do not act upon the hypervisor errors because + * there really isn't much we can do if they fail at this point. + */ + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_tx_qconf(%lx,%lx,%lx) failed, err=%lu\n", + lp->id, lp->tx_ra, lp->tx_num_entries, hv_err); + + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_tx_get_state(%lx,...) failed, err=%lu\n", + lp->id, hv_err); + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_rx_qconf(%lx,%lx,%lx) failed, err=%lu\n", + lp->id, lp->rx_ra, lp->rx_num_entries, hv_err); + + /* Refetch the RX queue state as well, because we could be invoked + * here in the queue processing context. + */ + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + printk(KERN_ERR PFX "ldc_abort: " + "sun4v_ldc_rx_get_state(%lx,...) failed, err=%lu\n", + lp->id, hv_err); + + return -ECONNRESET; +} + +static struct ldc_version *find_by_major(u16 major) +{ + struct ldc_version *ret = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(ver_arr); i++) { + struct ldc_version *v = &ver_arr[i]; + if (v->major <= major) { + ret = v; + break; + } + } + return ret; +} + +static int process_ver_info(struct ldc_channel *lp, struct ldc_version *vp) +{ + struct ldc_version *vap; + int err; + + ldcdbg(HS, "GOT VERSION INFO major[%x] minor[%x]\n", + vp->major, vp->minor); + + if (lp->hs_state == LDC_HS_GOTVERS) { + lp->hs_state = LDC_HS_OPEN; + memset(&lp->ver, 0, sizeof(lp->ver)); + } + + vap = find_by_major(vp->major); + if (!vap) { + err = send_version_nack(lp, 0, 0); + } else if (vap->major != vp->major) { + err = send_version_nack(lp, vap->major, vap->minor); + } else { + struct ldc_version ver = *vp; + if (ver.minor > vap->minor) + ver.minor = vap->minor; + err = send_version_ack(lp, &ver); + if (!err) { + lp->ver = ver; + lp->hs_state = LDC_HS_GOTVERS; + } + } + if (err) + return ldc_abort(lp); + + return 0; +} + +static int process_ver_ack(struct ldc_channel *lp, struct ldc_version *vp) +{ + ldcdbg(HS, "GOT VERSION ACK major[%x] minor[%x]\n", + vp->major, vp->minor); + + if (lp->hs_state == LDC_HS_GOTVERS) { + if (lp->ver.major != vp->major || + lp->ver.minor != vp->minor) + return ldc_abort(lp); + } else { + lp->ver = *vp; + lp->hs_state = LDC_HS_GOTVERS; + } + if (send_rts(lp)) + return ldc_abort(lp); + return 0; +} + +static int process_ver_nack(struct ldc_channel *lp, struct ldc_version *vp) +{ + struct ldc_version *vap; + + if ((vp->major == 0 && vp->minor == 0) || + !(vap = find_by_major(vp->major))) { + return ldc_abort(lp); + } else { + struct ldc_packet *p; + unsigned long new_tail; + + p = handshake_compose_ctrl(lp, LDC_INFO, LDC_VERS, + vap, sizeof(*vap), + &new_tail); + if (p) + return send_tx_packet(lp, p, new_tail); + else + return ldc_abort(lp); + } +} + +static int process_version(struct ldc_channel *lp, + struct ldc_packet *p) +{ + struct ldc_version *vp; + + vp = (struct ldc_version *) p->u.u_data; + + switch (p->stype) { + case LDC_INFO: + return process_ver_info(lp, vp); + + case LDC_ACK: + return process_ver_ack(lp, vp); + + case LDC_NACK: + return process_ver_nack(lp, vp); + + default: + return ldc_abort(lp); + } +} + +static int process_rts(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RTS stype[%x] seqid[%x] env[%x]\n", + p->stype, p->seqid, p->env); + + if (p->stype != LDC_INFO || + lp->hs_state != LDC_HS_GOTVERS || + p->env != lp->cfg.mode) + return ldc_abort(lp); + + lp->snd_nxt = p->seqid; + lp->rcv_nxt = p->seqid; + lp->hs_state = LDC_HS_SENTRTR; + if (send_rtr(lp)) + return ldc_abort(lp); + + return 0; +} + +static int process_rtr(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RTR stype[%x] seqid[%x] env[%x]\n", + p->stype, p->seqid, p->env); + + if (p->stype != LDC_INFO || + p->env != lp->cfg.mode) + return ldc_abort(lp); + + lp->snd_nxt = p->seqid; + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + send_rdx(lp); + + return LDC_EVENT_UP; +} + +static int rx_seq_ok(struct ldc_channel *lp, u32 seqid) +{ + return lp->rcv_nxt + 1 == seqid; +} + +static int process_rdx(struct ldc_channel *lp, + struct ldc_packet *p) +{ + ldcdbg(HS, "GOT RDX stype[%x] seqid[%x] env[%x] ackid[%x]\n", + p->stype, p->seqid, p->env, p->u.r.ackid); + + if (p->stype != LDC_INFO || + !(rx_seq_ok(lp, p->seqid))) + return ldc_abort(lp); + + lp->rcv_nxt = p->seqid; + + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + return LDC_EVENT_UP; +} + +static int process_control_frame(struct ldc_channel *lp, + struct ldc_packet *p) +{ + switch (p->ctrl) { + case LDC_VERS: + return process_version(lp, p); + + case LDC_RTS: + return process_rts(lp, p); + + case LDC_RTR: + return process_rtr(lp, p); + + case LDC_RDX: + return process_rdx(lp, p); + + default: + return ldc_abort(lp); + } +} + +static int process_error_frame(struct ldc_channel *lp, + struct ldc_packet *p) +{ + return ldc_abort(lp); +} + +static int process_data_ack(struct ldc_channel *lp, + struct ldc_packet *ack) +{ + unsigned long head = lp->tx_acked; + u32 ackid = ack->u.r.ackid; + + while (1) { + struct ldc_packet *p = lp->tx_base + (head / LDC_PACKET_SIZE); + + head = tx_advance(lp, head); + + if (p->seqid == ackid) { + lp->tx_acked = head; + return 0; + } + if (head == lp->tx_tail) + return ldc_abort(lp); + } + + return 0; +} + +static void send_events(struct ldc_channel *lp, unsigned int event_mask) +{ + if (event_mask & LDC_EVENT_RESET) + lp->cfg.event(lp->event_arg, LDC_EVENT_RESET); + if (event_mask & LDC_EVENT_UP) + lp->cfg.event(lp->event_arg, LDC_EVENT_UP); + if (event_mask & LDC_EVENT_DATA_READY) + lp->cfg.event(lp->event_arg, LDC_EVENT_DATA_READY); +} + +static irqreturn_t ldc_rx(int irq, void *dev_id) +{ + struct ldc_channel *lp = dev_id; + unsigned long orig_state, hv_err, flags; + unsigned int event_mask; + + spin_lock_irqsave(&lp->lock, flags); + + orig_state = lp->chan_state; + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + + ldcdbg(RX, "RX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", + orig_state, lp->chan_state, lp->rx_head, lp->rx_tail); + + event_mask = 0; + + if (lp->cfg.mode == LDC_MODE_RAW && + lp->chan_state == LDC_CHANNEL_UP) { + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + event_mask |= LDC_EVENT_UP; + + orig_state = lp->chan_state; + } + + /* If we are in reset state, flush the RX queue and ignore + * everything. + */ + if (lp->flags & LDC_FLAG_RESET) { + (void) __set_rx_head(lp, lp->rx_tail); + goto out; + } + + /* Once we finish the handshake, we let the ldc_read() + * paths do all of the control frame and state management. + * Just trigger the callback. + */ + if (lp->hs_state == LDC_HS_COMPLETE) { +handshake_complete: + if (lp->chan_state != orig_state) { + unsigned int event = LDC_EVENT_RESET; + + if (lp->chan_state == LDC_CHANNEL_UP) + event = LDC_EVENT_UP; + + event_mask |= event; + } + if (lp->rx_head != lp->rx_tail) + event_mask |= LDC_EVENT_DATA_READY; + + goto out; + } + + if (lp->chan_state != orig_state) + goto out; + + while (lp->rx_head != lp->rx_tail) { + struct ldc_packet *p; + unsigned long new; + int err; + + p = lp->rx_base + (lp->rx_head / LDC_PACKET_SIZE); + + switch (p->type) { + case LDC_CTRL: + err = process_control_frame(lp, p); + if (err > 0) + event_mask |= err; + break; + + case LDC_DATA: + event_mask |= LDC_EVENT_DATA_READY; + err = 0; + break; + + case LDC_ERR: + err = process_error_frame(lp, p); + break; + + default: + err = ldc_abort(lp); + break; + } + + if (err < 0) + break; + + new = lp->rx_head; + new += LDC_PACKET_SIZE; + if (new == (lp->rx_num_entries * LDC_PACKET_SIZE)) + new = 0; + lp->rx_head = new; + + err = __set_rx_head(lp, new); + if (err < 0) { + (void) ldc_abort(lp); + break; + } + if (lp->hs_state == LDC_HS_COMPLETE) + goto handshake_complete; + } + +out: + spin_unlock_irqrestore(&lp->lock, flags); + + send_events(lp, event_mask); + + return IRQ_HANDLED; +} + +static irqreturn_t ldc_tx(int irq, void *dev_id) +{ + struct ldc_channel *lp = dev_id; + unsigned long flags, hv_err, orig_state; + unsigned int event_mask = 0; + + spin_lock_irqsave(&lp->lock, flags); + + orig_state = lp->chan_state; + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + + ldcdbg(TX, " TX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", + orig_state, lp->chan_state, lp->tx_head, lp->tx_tail); + + if (lp->cfg.mode == LDC_MODE_RAW && + lp->chan_state == LDC_CHANNEL_UP) { + lp->hs_state = LDC_HS_COMPLETE; + ldc_set_state(lp, LDC_STATE_CONNECTED); + + event_mask |= LDC_EVENT_UP; + } + + spin_unlock_irqrestore(&lp->lock, flags); + + send_events(lp, event_mask); + + return IRQ_HANDLED; +} + +/* XXX ldc_alloc() and ldc_free() needs to run under a mutex so + * XXX that addition and removal from the ldc_channel_list has + * XXX atomicity, otherwise the __ldc_channel_exists() check is + * XXX totally pointless as another thread can slip into ldc_alloc() + * XXX and add a channel with the same ID. There also needs to be + * XXX a spinlock for ldc_channel_list. + */ +static HLIST_HEAD(ldc_channel_list); + +static int __ldc_channel_exists(unsigned long id) +{ + struct ldc_channel *lp; + struct hlist_node *n; + + hlist_for_each_entry(lp, n, &ldc_channel_list, list) { + if (lp->id == id) + return 1; + } + return 0; +} + +static int alloc_queue(const char *name, unsigned long num_entries, + struct ldc_packet **base, unsigned long *ra) +{ + unsigned long size, order; + void *q; + + size = num_entries * LDC_PACKET_SIZE; + order = get_order(size); + + q = (void *) __get_free_pages(GFP_KERNEL, order); + if (!q) { + printk(KERN_ERR PFX "Alloc of %s queue failed with " + "size=%lu order=%lu\n", name, size, order); + return -ENOMEM; + } + + memset(q, 0, PAGE_SIZE << order); + + *base = q; + *ra = __pa(q); + + return 0; +} + +static void free_queue(unsigned long num_entries, struct ldc_packet *q) +{ + unsigned long size, order; + + if (!q) + return; + + size = num_entries * LDC_PACKET_SIZE; + order = get_order(size); + + free_pages((unsigned long)q, order); +} + +/* XXX Make this configurable... XXX */ +#define LDC_IOTABLE_SIZE (8 * 1024) + +static int ldc_iommu_init(struct ldc_channel *lp) +{ + unsigned long sz, num_tsb_entries, tsbsize, order; + struct ldc_iommu *iommu = &lp->iommu; + struct ldc_mtable_entry *table; + unsigned long hv_err; + int err; + + num_tsb_entries = LDC_IOTABLE_SIZE; + tsbsize = num_tsb_entries * sizeof(struct ldc_mtable_entry); + + spin_lock_init(&iommu->lock); + + sz = num_tsb_entries / 8; + sz = (sz + 7UL) & ~7UL; + iommu->arena.map = kzalloc(sz, GFP_KERNEL); + if (!iommu->arena.map) { + printk(KERN_ERR PFX "Alloc of arena map failed, sz=%lu\n", sz); + return -ENOMEM; + } + + iommu->arena.limit = num_tsb_entries; + + order = get_order(tsbsize); + + table = (struct ldc_mtable_entry *) + __get_free_pages(GFP_KERNEL, order); + err = -ENOMEM; + if (!table) { + printk(KERN_ERR PFX "Alloc of MTE table failed, " + "size=%lu order=%lu\n", tsbsize, order); + goto out_free_map; + } + + memset(table, 0, PAGE_SIZE << order); + + iommu->page_table = table; + + hv_err = sun4v_ldc_set_map_table(lp->id, __pa(table), + num_tsb_entries); + err = -EINVAL; + if (hv_err) + goto out_free_table; + + return 0; + +out_free_table: + free_pages((unsigned long) table, order); + iommu->page_table = NULL; + +out_free_map: + kfree(iommu->arena.map); + iommu->arena.map = NULL; + + return err; +} + +static void ldc_iommu_release(struct ldc_channel *lp) +{ + struct ldc_iommu *iommu = &lp->iommu; + unsigned long num_tsb_entries, tsbsize, order; + + (void) sun4v_ldc_set_map_table(lp->id, 0, 0); + + num_tsb_entries = iommu->arena.limit; + tsbsize = num_tsb_entries * sizeof(struct ldc_mtable_entry); + order = get_order(tsbsize); + + free_pages((unsigned long) iommu->page_table, order); + iommu->page_table = NULL; + + kfree(iommu->arena.map); + iommu->arena.map = NULL; +} + +struct ldc_channel *ldc_alloc(unsigned long id, + const struct ldc_channel_config *cfgp, + void *event_arg) +{ + struct ldc_channel *lp; + const struct ldc_mode_ops *mops; + unsigned long dummy1, dummy2, hv_err; + u8 mss, *mssbuf; + int err; + + err = -ENODEV; + if (!ldom_domaining_enabled) + goto out_err; + + err = -EINVAL; + if (!cfgp) + goto out_err; + + switch (cfgp->mode) { + case LDC_MODE_RAW: + mops = &raw_ops; + mss = LDC_PACKET_SIZE; + break; + + case LDC_MODE_UNRELIABLE: + mops = &nonraw_ops; + mss = LDC_PACKET_SIZE - 8; + break; + + case LDC_MODE_STREAM: + mops = &stream_ops; + mss = LDC_PACKET_SIZE - 8 - 8; + break; + + default: + goto out_err; + } + + if (!cfgp->event || !event_arg || !cfgp->rx_irq || !cfgp->tx_irq) + goto out_err; + + hv_err = sun4v_ldc_tx_qinfo(id, &dummy1, &dummy2); + err = -ENODEV; + if (hv_err == HV_ECHANNEL) + goto out_err; + + err = -EEXIST; + if (__ldc_channel_exists(id)) + goto out_err; + + mssbuf = NULL; + + lp = kzalloc(sizeof(*lp), GFP_KERNEL); + err = -ENOMEM; + if (!lp) + goto out_err; + + spin_lock_init(&lp->lock); + + lp->id = id; + + err = ldc_iommu_init(lp); + if (err) + goto out_free_ldc; + + lp->mops = mops; + lp->mss = mss; + + lp->cfg = *cfgp; + if (!lp->cfg.mtu) + lp->cfg.mtu = LDC_DEFAULT_MTU; + + if (lp->cfg.mode == LDC_MODE_STREAM) { + mssbuf = kzalloc(lp->cfg.mtu, GFP_KERNEL); + if (!mssbuf) { + err = -ENOMEM; + goto out_free_iommu; + } + lp->mssbuf = mssbuf; + } + + lp->event_arg = event_arg; + + /* XXX allow setting via ldc_channel_config to override defaults + * XXX or use some formula based upon mtu + */ + lp->tx_num_entries = LDC_DEFAULT_NUM_ENTRIES; + lp->rx_num_entries = LDC_DEFAULT_NUM_ENTRIES; + + err = alloc_queue("TX", lp->tx_num_entries, + &lp->tx_base, &lp->tx_ra); + if (err) + goto out_free_mssbuf; + + err = alloc_queue("RX", lp->rx_num_entries, + &lp->rx_base, &lp->rx_ra); + if (err) + goto out_free_txq; + + lp->flags |= LDC_FLAG_ALLOCED_QUEUES; + + lp->hs_state = LDC_HS_CLOSED; + ldc_set_state(lp, LDC_STATE_INIT); + + INIT_HLIST_NODE(&lp->list); + hlist_add_head(&lp->list, &ldc_channel_list); + + INIT_HLIST_HEAD(&lp->mh_list); + + return lp; + +out_free_txq: + free_queue(lp->tx_num_entries, lp->tx_base); + +out_free_mssbuf: + if (mssbuf) + kfree(mssbuf); + +out_free_iommu: + ldc_iommu_release(lp); + +out_free_ldc: + kfree(lp); + +out_err: + return ERR_PTR(err); +} +EXPORT_SYMBOL(ldc_alloc); + +void ldc_free(struct ldc_channel *lp) +{ + if (lp->flags & LDC_FLAG_REGISTERED_IRQS) { + free_irq(lp->cfg.rx_irq, lp); + free_irq(lp->cfg.tx_irq, lp); + } + + if (lp->flags & LDC_FLAG_REGISTERED_QUEUES) { + sun4v_ldc_tx_qconf(lp->id, 0, 0); + sun4v_ldc_rx_qconf(lp->id, 0, 0); + lp->flags &= ~LDC_FLAG_REGISTERED_QUEUES; + } + if (lp->flags & LDC_FLAG_ALLOCED_QUEUES) { + free_queue(lp->tx_num_entries, lp->tx_base); + free_queue(lp->rx_num_entries, lp->rx_base); + lp->flags &= ~LDC_FLAG_ALLOCED_QUEUES; + } + + hlist_del(&lp->list); + + if (lp->mssbuf) + kfree(lp->mssbuf); + + ldc_iommu_release(lp); + + kfree(lp); +} +EXPORT_SYMBOL(ldc_free); + +/* Bind the channel. This registers the LDC queues with + * the hypervisor and puts the channel into a pseudo-listening + * state. This does not initiate a handshake, ldc_connect() does + * that. + */ +int ldc_bind(struct ldc_channel *lp, const char *name) +{ + unsigned long hv_err, flags; + int err = -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + if (!name) + goto out_err; + + if (lp->state != LDC_STATE_INIT) + goto out_err; + + snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); + snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); + + err = request_irq(lp->cfg.rx_irq, ldc_rx, + IRQF_SAMPLE_RANDOM | IRQF_SHARED, + lp->rx_irq_name, lp); + if (err) + goto out_err; + + err = request_irq(lp->cfg.tx_irq, ldc_tx, + IRQF_SAMPLE_RANDOM | IRQF_SHARED, + lp->tx_irq_name, lp); + if (err) + goto out_free_rx_irq; + + + lp->flags |= LDC_FLAG_REGISTERED_IRQS; + + err = -ENODEV; + hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_free_tx_irq; + + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + goto out_free_tx_irq; + + hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_unmap_tx; + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + goto out_unmap_tx; + + lp->flags |= LDC_FLAG_REGISTERED_QUEUES; + + hv_err = sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); + err = -EBUSY; + if (hv_err) + goto out_unmap_rx; + + lp->tx_acked = lp->tx_head; + + lp->hs_state = LDC_HS_OPEN; + ldc_set_state(lp, LDC_STATE_BOUND); + + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; + +out_unmap_rx: + lp->flags &= ~LDC_FLAG_REGISTERED_QUEUES; + sun4v_ldc_rx_qconf(lp->id, 0, 0); + +out_unmap_tx: + sun4v_ldc_tx_qconf(lp->id, 0, 0); + +out_free_tx_irq: + lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; + free_irq(lp->cfg.tx_irq, lp); + +out_free_rx_irq: + free_irq(lp->cfg.rx_irq, lp); + +out_err: + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_bind); + +int ldc_connect(struct ldc_channel *lp) +{ + unsigned long flags; + int err; + + if (lp->cfg.mode == LDC_MODE_RAW) + return -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || + !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) || + lp->hs_state != LDC_HS_OPEN) + err = -EINVAL; + else + err = start_handshake(lp); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_connect); + +int ldc_disconnect(struct ldc_channel *lp) +{ + unsigned long hv_err, flags; + int err; + + if (lp->cfg.mode == LDC_MODE_RAW) + return -EINVAL; + + if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || + !(lp->flags & LDC_FLAG_REGISTERED_QUEUES)) + return -EINVAL; + + spin_lock_irqsave(&lp->lock, flags); + + err = -ENODEV; + hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); + if (hv_err) + goto out_err; + + hv_err = sun4v_ldc_rx_qconf(lp->id, lp->rx_ra, lp->rx_num_entries); + if (hv_err) + goto out_err; + + ldc_set_state(lp, LDC_STATE_BOUND); + lp->hs_state = LDC_HS_OPEN; + lp->flags |= LDC_FLAG_RESET; + + spin_unlock_irqrestore(&lp->lock, flags); + + return 0; + +out_err: + sun4v_ldc_tx_qconf(lp->id, 0, 0); + sun4v_ldc_rx_qconf(lp->id, 0, 0); + free_irq(lp->cfg.tx_irq, lp); + free_irq(lp->cfg.rx_irq, lp); + lp->flags &= ~(LDC_FLAG_REGISTERED_IRQS | + LDC_FLAG_REGISTERED_QUEUES); + ldc_set_state(lp, LDC_STATE_INIT); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_disconnect); + +int ldc_state(struct ldc_channel *lp) +{ + return lp->state; +} +EXPORT_SYMBOL(ldc_state); + +static int write_raw(struct ldc_channel *lp, const void *buf, unsigned int size) +{ + struct ldc_packet *p; + unsigned long new_tail; + int err; + + if (size > LDC_PACKET_SIZE) + return -EMSGSIZE; + + p = data_get_tx_packet(lp, &new_tail); + if (!p) + return -EAGAIN; + + memcpy(p, buf, size); + + err = send_tx_packet(lp, p, new_tail); + if (!err) + err = size; + + return err; +} + +static int read_raw(struct ldc_channel *lp, void *buf, unsigned int size) +{ + struct ldc_packet *p; + unsigned long hv_err, new; + int err; + + if (size < LDC_PACKET_SIZE) + return -EINVAL; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (lp->rx_head == lp->rx_tail) + return 0; + + p = lp->rx_base + (lp->rx_head / LDC_PACKET_SIZE); + memcpy(buf, p, LDC_PACKET_SIZE); + + new = rx_advance(lp, lp->rx_head); + lp->rx_head = new; + + err = __set_rx_head(lp, new); + if (err < 0) + err = -ECONNRESET; + else + err = LDC_PACKET_SIZE; + + return err; +} + +static const struct ldc_mode_ops raw_ops = { + .write = write_raw, + .read = read_raw, +}; + +static int write_nonraw(struct ldc_channel *lp, const void *buf, + unsigned int size) +{ + unsigned long hv_err, tail; + unsigned int copied; + u32 seq; + int err; + + hv_err = sun4v_ldc_tx_get_state(lp->id, &lp->tx_head, &lp->tx_tail, + &lp->chan_state); + if (unlikely(hv_err)) + return -EBUSY; + + if (unlikely(lp->chan_state != LDC_CHANNEL_UP)) + return ldc_abort(lp); + + if (!tx_has_space_for(lp, size)) + return -EAGAIN; + + seq = lp->snd_nxt; + copied = 0; + tail = lp->tx_tail; + while (copied < size) { + struct ldc_packet *p = lp->tx_base + (tail / LDC_PACKET_SIZE); + u8 *data = ((lp->cfg.mode == LDC_MODE_UNRELIABLE) ? + p->u.u_data : + p->u.r.r_data); + int data_len; + + p->type = LDC_DATA; + p->stype = LDC_INFO; + p->ctrl = 0; + + data_len = size - copied; + if (data_len > lp->mss) + data_len = lp->mss; + + BUG_ON(data_len > LDC_LEN); + + p->env = (data_len | + (copied == 0 ? LDC_START : 0) | + (data_len == size - copied ? LDC_STOP : 0)); + + p->seqid = ++seq; + + ldcdbg(DATA, "SENT DATA [%02x:%02x:%02x:%02x:%08x]\n", + p->type, + p->stype, + p->ctrl, + p->env, + p->seqid); + + memcpy(data, buf, data_len); + buf += data_len; + copied += data_len; + + tail = tx_advance(lp, tail); + } + + err = set_tx_tail(lp, tail); + if (!err) { + lp->snd_nxt = seq; + err = size; + } + + return err; +} + +static int rx_bad_seq(struct ldc_channel *lp, struct ldc_packet *p, + struct ldc_packet *first_frag) +{ + int err; + + if (first_frag) + lp->rcv_nxt = first_frag->seqid - 1; + + err = send_data_nack(lp, p); + if (err) + return err; + + err = __set_rx_head(lp, lp->rx_tail); + if (err < 0) + return ldc_abort(lp); + + return 0; +} + +static int data_ack_nack(struct ldc_channel *lp, struct ldc_packet *p) +{ + if (p->stype & LDC_ACK) { + int err = process_data_ack(lp, p); + if (err) + return err; + } + if (p->stype & LDC_NACK) + return ldc_abort(lp); + + return 0; +} + +static int rx_data_wait(struct ldc_channel *lp, unsigned long cur_head) +{ + unsigned long dummy; + int limit = 1000; + + ldcdbg(DATA, "DATA WAIT cur_head[%lx] rx_head[%lx] rx_tail[%lx]\n", + cur_head, lp->rx_head, lp->rx_tail); + while (limit-- > 0) { + unsigned long hv_err; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &dummy, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (cur_head != lp->rx_tail) { + ldcdbg(DATA, "DATA WAIT DONE " + "head[%lx] tail[%lx] chan_state[%lx]\n", + dummy, lp->rx_tail, lp->chan_state); + return 0; + } + + udelay(1); + } + return -EAGAIN; +} + +static int rx_set_head(struct ldc_channel *lp, unsigned long head) +{ + int err = __set_rx_head(lp, head); + + if (err < 0) + return ldc_abort(lp); + + lp->rx_head = head; + return 0; +} + +static void send_data_ack(struct ldc_channel *lp) +{ + unsigned long new_tail; + struct ldc_packet *p; + + p = data_get_tx_packet(lp, &new_tail); + if (likely(p)) { + int err; + + memset(p, 0, sizeof(*p)); + p->type = LDC_DATA; + p->stype = LDC_ACK; + p->ctrl = 0; + p->seqid = lp->snd_nxt + 1; + p->u.r.ackid = lp->rcv_nxt; + + err = send_tx_packet(lp, p, new_tail); + if (!err) + lp->snd_nxt++; + } +} + +static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) +{ + struct ldc_packet *first_frag; + unsigned long hv_err, new; + int err, copied; + + hv_err = sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); + if (hv_err) + return ldc_abort(lp); + + if (lp->chan_state == LDC_CHANNEL_DOWN || + lp->chan_state == LDC_CHANNEL_RESETTING) + return -ECONNRESET; + + if (lp->rx_head == lp->rx_tail) + return 0; + + first_frag = NULL; + copied = err = 0; + new = lp->rx_head; + while (1) { + struct ldc_packet *p; + int pkt_len; + + BUG_ON(new == lp->rx_tail); + p = lp->rx_base + (new / LDC_PACKET_SIZE); + + ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x:%08x] " + "rcv_nxt[%08x]\n", + p->type, + p->stype, + p->ctrl, + p->env, + p->seqid, + p->u.r.ackid, + lp->rcv_nxt); + + if (unlikely(!rx_seq_ok(lp, p->seqid))) { + err = rx_bad_seq(lp, p, first_frag); + copied = 0; + break; + } + + if (p->type & LDC_CTRL) { + err = process_control_frame(lp, p); + if (err < 0) + break; + err = 0; + } + + lp->rcv_nxt = p->seqid; + + if (!(p->type & LDC_DATA)) { + new = rx_advance(lp, new); + goto no_data; + } + if (p->stype & (LDC_ACK | LDC_NACK)) { + err = data_ack_nack(lp, p); + if (err) + break; + } + if (!(p->stype & LDC_INFO)) { + new = rx_advance(lp, new); + err = rx_set_head(lp, new); + if (err) + break; + goto no_data; + } + + pkt_len = p->env & LDC_LEN; + + /* Every initial packet starts with the START bit set. + * + * Singleton packets will have both START+STOP set. + * + * Fragments will have START set in the first frame, STOP + * set in the last frame, and neither bit set in middle + * frames of the packet. + * + * Therefore if we are at the beginning of a packet and + * we don't see START, or we are in the middle of a fragmented + * packet and do see START, we are unsynchronized and should + * flush the RX queue. + */ + if ((first_frag == NULL && !(p->env & LDC_START)) || + (first_frag != NULL && (p->env & LDC_START))) { + if (!first_frag) + new = rx_advance(lp, new); + + err = rx_set_head(lp, new); + if (err) + break; + + if (!first_frag) + goto no_data; + } + if (!first_frag) + first_frag = p; + + if (pkt_len > size - copied) { + /* User didn't give us a big enough buffer, + * what to do? This is a pretty serious error. + * + * Since we haven't updated the RX ring head to + * consume any of the packets, signal the error + * to the user and just leave the RX ring alone. + * + * This seems the best behavior because this allows + * a user of the LDC layer to start with a small + * RX buffer for ldc_read() calls and use -EMSGSIZE + * as a cue to enlarge it's read buffer. + */ + err = -EMSGSIZE; + break; + } + + /* Ok, we are gonna eat this one. */ + new = rx_advance(lp, new); + + memcpy(buf, + (lp->cfg.mode == LDC_MODE_UNRELIABLE ? + p->u.u_data : p->u.r.r_data), pkt_len); + buf += pkt_len; + copied += pkt_len; + + if (p->env & LDC_STOP) + break; + +no_data: + if (new == lp->rx_tail) { + err = rx_data_wait(lp, new); + if (err) + break; + } + } + + if (!err) + err = rx_set_head(lp, new); + + if (err && first_frag) + lp->rcv_nxt = first_frag->seqid - 1; + + if (!err) { + err = copied; + if (err > 0 && lp->cfg.mode != LDC_MODE_UNRELIABLE) + send_data_ack(lp); + } + + return err; +} + +static const struct ldc_mode_ops nonraw_ops = { + .write = write_nonraw, + .read = read_nonraw, +}; + +static int write_stream(struct ldc_channel *lp, const void *buf, + unsigned int size) +{ + if (size > lp->cfg.mtu) + size = lp->cfg.mtu; + return write_nonraw(lp, buf, size); +} + +static int read_stream(struct ldc_channel *lp, void *buf, unsigned int size) +{ + if (!lp->mssbuf_len) { + int err = read_nonraw(lp, lp->mssbuf, lp->cfg.mtu); + if (err < 0) + return err; + + lp->mssbuf_len = err; + lp->mssbuf_off = 0; + } + + if (size > lp->mssbuf_len) + size = lp->mssbuf_len; + memcpy(buf, lp->mssbuf + lp->mssbuf_off, size); + + lp->mssbuf_off += size; + lp->mssbuf_len -= size; + + return size; +} + +static const struct ldc_mode_ops stream_ops = { + .write = write_stream, + .read = read_stream, +}; + +int ldc_write(struct ldc_channel *lp, const void *buf, unsigned int size) +{ + unsigned long flags; + int err; + + if (!buf) + return -EINVAL; + + if (!size) + return 0; + + spin_lock_irqsave(&lp->lock, flags); + + if (lp->hs_state != LDC_HS_COMPLETE) + err = -ENOTCONN; + else + err = lp->mops->write(lp, buf, size); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_write); + +int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size) +{ + unsigned long flags; + int err; + + if (!buf) + return -EINVAL; + + if (!size) + return 0; + + spin_lock_irqsave(&lp->lock, flags); + + if (lp->hs_state != LDC_HS_COMPLETE) + err = -ENOTCONN; + else + err = lp->mops->read(lp, buf, size); + + spin_unlock_irqrestore(&lp->lock, flags); + + return err; +} +EXPORT_SYMBOL(ldc_read); + +static long arena_alloc(struct ldc_iommu *iommu, unsigned long npages) +{ + struct iommu_arena *arena = &iommu->arena; + unsigned long n, i, start, end, limit; + int pass; + + limit = arena->limit; + start = arena->hint; + pass = 0; + +again: + n = find_next_zero_bit(arena->map, limit, start); + end = n + npages; + if (unlikely(end >= limit)) { + if (likely(pass < 1)) { + limit = start; + start = 0; + pass++; + goto again; + } else { + /* Scanned the whole thing, give up. */ + return -1; + } + } + + for (i = n; i < end; i++) { + if (test_bit(i, arena->map)) { + start = i + 1; + goto again; + } + } + + for (i = n; i < end; i++) + __set_bit(i, arena->map); + + arena->hint = end; + + return n; +} + +#define COOKIE_PGSZ_CODE 0xf000000000000000ULL +#define COOKIE_PGSZ_CODE_SHIFT 60ULL + +static u64 pagesize_code(void) +{ + switch (PAGE_SIZE) { + default: + case (8ULL * 1024ULL): + return 0; + case (64ULL * 1024ULL): + return 1; + case (512ULL * 1024ULL): + return 2; + case (4ULL * 1024ULL * 1024ULL): + return 3; + case (32ULL * 1024ULL * 1024ULL): + return 4; + case (256ULL * 1024ULL * 1024ULL): + return 5; + } +} + +static u64 make_cookie(u64 index, u64 pgsz_code, u64 page_offset) +{ + return ((pgsz_code << COOKIE_PGSZ_CODE_SHIFT) | + (index << PAGE_SHIFT) | + page_offset); +} + +static u64 cookie_to_index(u64 cookie, unsigned long *shift) +{ + u64 szcode = cookie >> COOKIE_PGSZ_CODE_SHIFT; + + cookie &= ~COOKIE_PGSZ_CODE; + + *shift = szcode * 3; + + return (cookie >> (13ULL + (szcode * 3ULL))); +} + +static struct ldc_mtable_entry *alloc_npages(struct ldc_iommu *iommu, + unsigned long npages) +{ + long entry; + + entry = arena_alloc(iommu, npages); + if (unlikely(entry < 0)) + return NULL; + + return iommu->page_table + entry; +} + +static u64 perm_to_mte(unsigned int map_perm) +{ + u64 mte_base; + + mte_base = pagesize_code(); + + if (map_perm & LDC_MAP_SHADOW) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_COPY_R; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_COPY_W; + } + if (map_perm & LDC_MAP_DIRECT) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_READ; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_WRITE; + if (map_perm & LDC_MAP_X) + mte_base |= LDC_MTE_EXEC; + } + if (map_perm & LDC_MAP_IO) { + if (map_perm & LDC_MAP_R) + mte_base |= LDC_MTE_IOMMU_R; + if (map_perm & LDC_MAP_W) + mte_base |= LDC_MTE_IOMMU_W; + } + + return mte_base; +} + +static int pages_in_region(unsigned long base, long len) +{ + int count = 0; + + do { + unsigned long new = (base + PAGE_SIZE) & PAGE_MASK; + + len -= (new - base); + base = new; + count++; + } while (len > 0); + + return count; +} + +struct cookie_state { + struct ldc_mtable_entry *page_table; + struct ldc_trans_cookie *cookies; + u64 mte_base; + u64 prev_cookie; + u32 pte_idx; + u32 nc; +}; + +static void fill_cookies(struct cookie_state *sp, unsigned long pa, + unsigned long off, unsigned long len) +{ + do { + unsigned long tlen, new = pa + PAGE_SIZE; + u64 this_cookie; + + sp->page_table[sp->pte_idx].mte = sp->mte_base | pa; + + tlen = PAGE_SIZE; + if (off) + tlen = PAGE_SIZE - off; + if (tlen > len) + tlen = len; + + this_cookie = make_cookie(sp->pte_idx, + pagesize_code(), off); + + off = 0; + + if (this_cookie == sp->prev_cookie) { + sp->cookies[sp->nc - 1].cookie_size += tlen; + } else { + sp->cookies[sp->nc].cookie_addr = this_cookie; + sp->cookies[sp->nc].cookie_size = tlen; + sp->nc++; + } + sp->prev_cookie = this_cookie + tlen; + + sp->pte_idx++; + + len -= tlen; + pa = new; + } while (len > 0); +} + +static int sg_count_one(struct scatterlist *sg) +{ + unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT; + long len = sg->length; + + if ((sg->offset | len) & (8UL - 1)) + return -EFAULT; + + return pages_in_region(base + sg->offset, len); +} + +static int sg_count_pages(struct scatterlist *sg, int num_sg) +{ + int count; + int i; + + count = 0; + for (i = 0; i < num_sg; i++) { + int err = sg_count_one(sg + i); + if (err < 0) + return err; + count += err; + } + + return count; +} + +int ldc_map_sg(struct ldc_channel *lp, + struct scatterlist *sg, int num_sg, + struct ldc_trans_cookie *cookies, int ncookies, + unsigned int map_perm) +{ + unsigned long i, npages, flags; + struct ldc_mtable_entry *base; + struct cookie_state state; + struct ldc_iommu *iommu; + int err; + + if (map_perm & ~LDC_MAP_ALL) + return -EINVAL; + + err = sg_count_pages(sg, num_sg); + if (err < 0) + return err; + + npages = err; + if (err > ncookies) + return -EMSGSIZE; + + iommu = &lp->iommu; + + spin_lock_irqsave(&iommu->lock, flags); + base = alloc_npages(iommu, npages); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (!base) + return -ENOMEM; + + state.page_table = iommu->page_table; + state.cookies = cookies; + state.mte_base = perm_to_mte(map_perm); + state.prev_cookie = ~(u64)0; + state.pte_idx = (base - iommu->page_table); + state.nc = 0; + + for (i = 0; i < num_sg; i++) + fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT, + sg[i].offset, sg[i].length); + + return state.nc; +} +EXPORT_SYMBOL(ldc_map_sg); + +int ldc_map_single(struct ldc_channel *lp, + void *buf, unsigned int len, + struct ldc_trans_cookie *cookies, int ncookies, + unsigned int map_perm) +{ + unsigned long npages, pa, flags; + struct ldc_mtable_entry *base; + struct cookie_state state; + struct ldc_iommu *iommu; + + if ((map_perm & ~LDC_MAP_ALL) || (ncookies < 1)) + return -EINVAL; + + pa = __pa(buf); + if ((pa | len) & (8UL - 1)) + return -EFAULT; + + npages = pages_in_region(pa, len); + + iommu = &lp->iommu; + + spin_lock_irqsave(&iommu->lock, flags); + base = alloc_npages(iommu, npages); + spin_unlock_irqrestore(&iommu->lock, flags); + + if (!base) + return -ENOMEM; + + state.page_table = iommu->page_table; + state.cookies = cookies; + state.mte_base = perm_to_mte(map_perm); + state.prev_cookie = ~(u64)0; + state.pte_idx = (base - iommu->page_table); + state.nc = 0; + fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len); + BUG_ON(state.nc != 1); + + return state.nc; +} +EXPORT_SYMBOL(ldc_map_single); + +static void free_npages(unsigned long id, struct ldc_iommu *iommu, + u64 cookie, u64 size) +{ + struct iommu_arena *arena = &iommu->arena; + unsigned long i, shift, index, npages; + struct ldc_mtable_entry *base; + + npages = PAGE_ALIGN(((cookie & ~PAGE_MASK) + size)) >> PAGE_SHIFT; + index = cookie_to_index(cookie, &shift); + base = iommu->page_table + index; + + BUG_ON(index > arena->limit || + (index + npages) > arena->limit); + + for (i = 0; i < npages; i++) { + if (base->cookie) + sun4v_ldc_revoke(id, cookie + (i << shift), + base->cookie); + base->mte = 0; + __clear_bit(index + i, arena->map); + } +} + +void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies, + int ncookies) +{ + struct ldc_iommu *iommu = &lp->iommu; + unsigned long flags; + int i; + + spin_lock_irqsave(&iommu->lock, flags); + for (i = 0; i < ncookies; i++) { + u64 addr = cookies[i].cookie_addr; + u64 size = cookies[i].cookie_size; + + free_npages(lp->id, iommu, addr, size); + } + spin_unlock_irqrestore(&iommu->lock, flags); +} +EXPORT_SYMBOL(ldc_unmap); + +int ldc_copy(struct ldc_channel *lp, int copy_dir, + void *buf, unsigned int len, unsigned long offset, + struct ldc_trans_cookie *cookies, int ncookies) +{ + unsigned int orig_len; + unsigned long ra; + int i; + + if (copy_dir != LDC_COPY_IN && copy_dir != LDC_COPY_OUT) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Bad copy_dir[%d]\n", + lp->id, copy_dir); + return -EINVAL; + } + + ra = __pa(buf); + if ((ra | len | offset) & (8UL - 1)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Unaligned buffer " + "ra[%lx] len[%x] offset[%lx]\n", + lp->id, ra, len, offset); + return -EFAULT; + } + + if (lp->hs_state != LDC_HS_COMPLETE || + (lp->flags & LDC_FLAG_RESET)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] Link down hs_state[%x] " + "flags[%x]\n", lp->id, lp->hs_state, lp->flags); + return -ECONNRESET; + } + + orig_len = len; + for (i = 0; i < ncookies; i++) { + unsigned long cookie_raddr = cookies[i].cookie_addr; + unsigned long this_len = cookies[i].cookie_size; + unsigned long actual_len; + + if (unlikely(offset)) { + unsigned long this_off = offset; + + if (this_off > this_len) + this_off = this_len; + + offset -= this_off; + this_len -= this_off; + if (!this_len) + continue; + cookie_raddr += this_off; + } + + if (this_len > len) + this_len = len; + + while (1) { + unsigned long hv_err; + + hv_err = sun4v_ldc_copy(lp->id, copy_dir, + cookie_raddr, ra, + this_len, &actual_len); + if (unlikely(hv_err)) { + printk(KERN_ERR PFX "ldc_copy: ID[%lu] " + "HV error %lu\n", + lp->id, hv_err); + if (lp->hs_state != LDC_HS_COMPLETE || + (lp->flags & LDC_FLAG_RESET)) + return -ECONNRESET; + else + return -EFAULT; + } + + cookie_raddr += actual_len; + ra += actual_len; + len -= actual_len; + if (actual_len == this_len) + break; + + this_len -= actual_len; + } + + if (!len) + break; + } + + /* It is caller policy what to do about short copies. + * For example, a networking driver can declare the + * packet a runt and drop it. + */ + + return orig_len - len; +} +EXPORT_SYMBOL(ldc_copy); + +void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, + struct ldc_trans_cookie *cookies, int *ncookies, + unsigned int map_perm) +{ + void *buf; + int err; + + if (len & (8UL - 1)) + return ERR_PTR(-EINVAL); + + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + err = ldc_map_single(lp, buf, len, cookies, *ncookies, map_perm); + if (err < 0) { + kfree(buf); + return ERR_PTR(err); + } + *ncookies = err; + + return buf; +} +EXPORT_SYMBOL(ldc_alloc_exp_dring); + +void ldc_free_exp_dring(struct ldc_channel *lp, void *buf, unsigned int len, + struct ldc_trans_cookie *cookies, int ncookies) +{ + ldc_unmap(lp, cookies, ncookies); + kfree(buf); +} +EXPORT_SYMBOL(ldc_free_exp_dring); + +static int __init ldc_init(void) +{ + unsigned long major, minor; + struct mdesc_handle *hp; + const u64 *v; + u64 mp; + + hp = mdesc_grab(); + if (!hp) + return -ENODEV; + + mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform"); + if (mp == MDESC_NODE_NULL) + return -ENODEV; + + v = mdesc_get_property(hp, mp, "domaining-enabled", NULL); + if (!v) + return -ENODEV; + + major = 1; + minor = 0; + if (sun4v_hvapi_register(HV_GRP_LDOM, major, &minor)) { + printk(KERN_INFO PFX "Could not register LDOM hvapi.\n"); + return -ENODEV; + } + + printk(KERN_INFO "%s", version); + + if (!*v) { + printk(KERN_INFO PFX "Domaining disabled.\n"); + return -ENODEV; + } + ldom_domaining_enabled = 1; + + return 0; +} + +core_initcall(ldc_init); --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/chmc.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/chmc.c @@ -1,7 +1,6 @@ -/* $Id: chmc.c,v 1.4 2002/01/08 16:00:14 davem Exp $ - * memctrlr.c: Driver for UltraSPARC-III memory controller. +/* memctrlr.c: Driver for UltraSPARC-III memory controller. * - * Copyright (C) 2001 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -242,8 +242,11 @@ */ static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset) { - unsigned long ret; - int this_cpu = get_cpu(); + unsigned long ret, this_cpu; + + preempt_disable(); + + this_cpu = real_hard_smp_processor_id(); if (mp->portid == this_cpu) { __asm__ __volatile__("ldxa [%1] %2, %0" @@ -255,7 +258,8 @@ : "r" (mp->regs + offset), "i" (ASI_PHYS_BYPASS_EC_E)); } - put_cpu(); + + preempt_enable(); return ret; } --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/pci_sun4v.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/pci_sun4v.c @@ -928,13 +928,13 @@ if (msi_num < 0) return msi_num; - devino = sun4v_build_msi(pbm->devhandle, virt_irq_p, - pbm->msiq_first_devino, - (pbm->msiq_first_devino + - pbm->msiq_num)); - err = -ENOMEM; - if (!devino) + err = sun4v_build_msi(pbm->devhandle, virt_irq_p, + pbm->msiq_first_devino, + (pbm->msiq_first_devino + + pbm->msiq_num)); + if (err < 0) goto out_err; + devino = err; msiqid = ((devino - pbm->msiq_first_devino) + pbm->msiq_first); @@ -959,7 +959,7 @@ if (pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_VALID)) goto out_err; - pdev->dev.archdata.msi_num = msi_num; + sparc64_set_msi(*virt_irq_p, msi_num); if (entry->msi_attrib.is_64) { msg.address_hi = pbm->msi64_start >> 32; @@ -981,8 +981,6 @@ out_err: free_msi(pbm, msi_num); - sun4v_destroy_msi(*virt_irq_p); - *virt_irq_p = 0; return err; } @@ -994,7 +992,7 @@ unsigned long msiqid, err; unsigned int msi_num; - msi_num = pdev->dev.archdata.msi_num; + msi_num = sparc64_get_msi(virt_irq); err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi_num, &msiqid); if (err) { printk(KERN_ERR "%s: getmsiq gives error %lu\n", @@ -1129,7 +1127,7 @@ } #endif /* !(CONFIG_PCI_MSI) */ -static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) +static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) { struct pci_pbm_info *pbm; @@ -1163,7 +1161,7 @@ pci_sun4v_msi_init(pbm); } -void sun4v_pci_init(struct device_node *dp, char *model_name) +void __init sun4v_pci_init(struct device_node *dp, char *model_name) { static int hvapi_negotiated = 0; struct pci_controller_info *p; --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/entry.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/entry.S @@ -2593,3 +2593,15 @@ retl nop .size sun4v_mmustat_info, .-sun4v_mmustat_info + + .globl sun4v_mmu_demap_all + .type sun4v_mmu_demap_all,#function +sun4v_mmu_demap_all: + clr %o0 + clr %o1 + mov HV_MMU_ALL, %o2 + mov HV_FAST_MMU_DEMAP_ALL, %o5 + ta HV_FAST_TRAP + retl + nop + .size sun4v_mmu_demap_all, .-sun4v_mmu_demap_all --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/kernel/pci_common.c +++ linux-source-2.6.22-2.6.22/arch/sparc64/kernel/pci_common.c @@ -44,6 +44,67 @@ return (void *) (pbm->config_space | bus | devfn | reg); } +/* At least on Sabre, it is necessary to access all PCI host controller + * registers at their natural size, otherwise zeros are returned. + * Strange but true, and I see no language in the UltraSPARC-IIi + * programmer's manual that mentions this even indirectly. + */ +static int sun4u_read_pci_cfg_host(struct pci_pbm_info *pbm, + unsigned char bus, unsigned int devfn, + int where, int size, u32 *value) +{ + u32 tmp32, *addr; + u16 tmp16; + u8 tmp8; + + addr = sun4u_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + switch (size) { + case 1: + if (where < 8) { + unsigned long align = (unsigned long) addr; + + align &= ~1; + pci_config_read16((u16 *)align, &tmp16); + if (where & 1) + *value = tmp16 >> 8; + else + *value = tmp16 & 0xff; + } else { + pci_config_read8((u8 *)addr, &tmp8); + *value = (u32) tmp8; + } + break; + + case 2: + if (where < 8) { + pci_config_read16((u16 *)addr, &tmp16); + *value = (u32) tmp16; + } else { + pci_config_read8((u8 *)addr, &tmp8); + *value = (u32) tmp8; + pci_config_read8(((u8 *)addr) + 1, &tmp8); + *value |= ((u32) tmp8) << 8; + } + break; + + case 4: + tmp32 = 0xffffffff; + sun4u_read_pci_cfg_host(pbm, bus, devfn, + where, 2, &tmp32); + *value = tmp32; + + tmp32 = 0xffffffff; + sun4u_read_pci_cfg_host(pbm, bus, devfn, + where + 2, 2, &tmp32); + *value |= tmp32 << 16; + break; + } + return PCIBIOS_SUCCESSFUL; +} + static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value) { @@ -53,10 +114,6 @@ u16 tmp16; u8 tmp8; - if (bus_dev == pbm->pci_bus && devfn == 0x00) - return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, - size, value); - switch (size) { case 1: *value = 0xff; @@ -69,6 +126,10 @@ break; } + if (!bus_dev->number && !PCI_SLOT(devfn)) + return sun4u_read_pci_cfg_host(pbm, bus, devfn, where, + size, value); + addr = sun4u_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; @@ -101,6 +162,53 @@ return PCIBIOS_SUCCESSFUL; } +static int sun4u_write_pci_cfg_host(struct pci_pbm_info *pbm, + unsigned char bus, unsigned int devfn, + int where, int size, u32 value) +{ + u32 *addr; + + addr = sun4u_config_mkaddr(pbm, bus, devfn, where); + if (!addr) + return PCIBIOS_SUCCESSFUL; + + switch (size) { + case 1: + if (where < 8) { + unsigned long align = (unsigned long) addr; + u16 tmp16; + + align &= ~1; + pci_config_read16((u16 *)align, &tmp16); + if (where & 1) { + tmp16 &= 0x00ff; + tmp16 |= value << 8; + } else { + tmp16 &= 0xff00; + tmp16 |= value; + } + pci_config_write16((u16 *)align, tmp16); + } else + pci_config_write8((u8 *)addr, value); + break; + case 2: + if (where < 8) { + pci_config_write16((u16 *)addr, value); + } else { + pci_config_write8((u8 *)addr, value & 0xff); + pci_config_write8(((u8 *)addr) + 1, value >> 8); + } + break; + case 4: + sun4u_write_pci_cfg_host(pbm, bus, devfn, + where, 2, value & 0xffff); + sun4u_write_pci_cfg_host(pbm, bus, devfn, + where + 2, 2, value >> 16); + break; + } + return PCIBIOS_SUCCESSFUL; +} + static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value) { @@ -108,9 +216,10 @@ unsigned char bus = bus_dev->number; u32 *addr; - if (bus_dev == pbm->pci_bus && devfn == 0x00) - return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, - size, value); + if (!bus_dev->number && !PCI_SLOT(devfn)) + return sun4u_write_pci_cfg_host(pbm, bus, devfn, where, + size, value); + addr = sun4u_config_mkaddr(pbm, bus, devfn, where); if (!addr) return PCIBIOS_SUCCESSFUL; --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/Kconfig +++ linux-source-2.6.22-2.6.22/arch/sparc64/Kconfig @@ -108,6 +108,15 @@ source kernel/Kconfig.hz +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP + select HOTPLUG + ---help--- + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu/cpu#. + Say N if you want to disable CPU hotplug. + source "init/Kconfig" config SYSVIPC_COMPAT @@ -305,6 +314,12 @@ bool default y +config SUN_LDOMS + bool "Sun Logical Domains support" + help + Say Y here is you want to support virtual devices via + Logical Domains. + config PCI bool "PCI support" select ARCH_SUPPORTS_MSI --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NGcopy_to_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NGcopy_to_user.S @@ -1,6 +1,6 @@ /* NGcopy_to_user.S: Niagara optimized copy to userspace. * - * Copyright (C) 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) */ #define EX_ST(x) \ @@ -8,8 +8,8 @@ .section .fixup; \ .align 4; \ 99: wr %g0, ASI_AIUS, %asi;\ - retl; \ - mov 1, %o0; \ + ret; \ + restore %g0, 1, %o0; \ .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ @@ -23,7 +23,7 @@ #define FUNC_NAME NGcopy_to_user #define STORE(type,src,addr) type##a src, [addr] ASI_AIUS #define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS -#define EX_RETVAL(x) 0 +#define EX_RETVAL(x) %g0 #ifdef __KERNEL__ /* Writing to %asi is _expensive_ so we hardcode it. --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENpatch.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENpatch.S @@ -0,0 +1,33 @@ +/* GENpatch.S: Patch Ultra-I routines with generic variant. + * + * Copyright (C) 2007 David S. Miller + */ + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define GEN_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl generic_patch_copyops + .type generic_patch_copyops,#function +generic_patch_copyops: + GEN_DO_PATCH(memcpy, GENmemcpy) + GEN_DO_PATCH(___copy_from_user, GENcopy_from_user) + GEN_DO_PATCH(___copy_to_user, GENcopy_to_user) + retl + nop + .size generic_patch_copyops,.-generic_patch_copyops --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NG2copy_to_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NG2copy_to_user.S @@ -0,0 +1,49 @@ +/* NG2copy_to_user.S: Niagara-2 optimized copy to userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_ST(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_AIUS_4V +#define ASI_BLK_AIUS_4V 0x17 +#endif + +#ifndef ASI_BLK_INIT_QUAD_LDD_AIUS +#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 +#endif + +#define FUNC_NAME NG2copy_to_user +#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS +#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS_4V +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "NG2memcpy.S" --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENcopy_from_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENcopy_from_user.S @@ -0,0 +1,34 @@ +/* GENcopy_from_user.S: Generic sparc64 copy from userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_LD(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#define FUNC_NAME GENcopy_from_user +#define LOAD(type,addr,dest) type##a [addr] ASI_AIUS, dest +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "GENmemcpy.S" --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/Makefile +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.25 2000/12/14 22:57:25 davem Exp $ +# # Makefile for Sparc64 library files.. # @@ -13,7 +13,11 @@ U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \ NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \ NGpage.o NGbzero.o \ + NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o NG2patch.o \ + NG2page.o \ + GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o GENpatch.o \ + GENpage.o GENbzero.o \ copy_in_user.o user_fixup.o memmove.o \ - mcount.o ipcsum.o rwsem.o xor.o delay.o + mcount.o ipcsum.o rwsem.o xor.o obj-y += iomap.o --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/xor.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/xor.S @@ -491,12 +491,12 @@ ldda [%i1 + 0x10] %asi, %i2 /* %i2/%i3 = src1 + 0x10 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */ + ldda [%l7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x00] %asi stxa %l1, [%i0 + 0x08] %asi - ldda [%i6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */ + ldda [%l6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */ ldda [%i0 + 0x10] %asi, %l0 /* %l0/%l1 = dest + 0x10 */ xor %i4, %i2, %i4 @@ -504,12 +504,12 @@ ldda [%i1 + 0x20] %asi, %i2 /* %i2/%i3 = src1 + 0x20 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */ + ldda [%l7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x10] %asi stxa %l1, [%i0 + 0x18] %asi - ldda [%i6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */ + ldda [%l6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */ ldda [%i0 + 0x20] %asi, %l0 /* %l0/%l1 = dest + 0x20 */ xor %i4, %i2, %i4 @@ -517,12 +517,12 @@ ldda [%i1 + 0x30] %asi, %i2 /* %i2/%i3 = src1 + 0x30 */ xor %g2, %i4, %g2 xor %g3, %i5, %g3 - ldda [%i7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */ + ldda [%l7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */ xor %l0, %g2, %l0 xor %l1, %g3, %l1 stxa %l0, [%i0 + 0x20] %asi stxa %l1, [%i0 + 0x28] %asi - ldda [%i6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */ + ldda [%l6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */ ldda [%i0 + 0x30] %asi, %l0 /* %l0/%l1 = dest + 0x30 */ prefetch [%i1 + 0x40], #one_read --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NG2copy_from_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NG2copy_from_user.S @@ -0,0 +1,40 @@ +/* NG2copy_from_user.S: Niagara-2 optimized copy from userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_LD(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_AIUS_4V +#define ASI_BLK_AIUS_4V 0x17 +#endif + +#define FUNC_NAME NG2copy_from_user +#define LOAD(type,addr,dest) type##a [addr] %asi, dest +#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_AIUS_4V, dest +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "NG2memcpy.S" --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NG2page.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NG2page.S @@ -0,0 +1,61 @@ +/* NG2page.S: Niagara-2 optimized clear and copy page. + * + * Copyright (C) 2007 (davem@davemloft.net) + */ + +#include +#include +#include + + .text + .align 32 + + /* This is heavily simplified from the sun4u variants + * because Niagara-2 does not have any D-cache aliasing issues. + */ +NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ + prefetch [%o1 + 0x00], #one_read + prefetch [%o1 + 0x40], #one_read + VISEntryHalf + set PAGE_SIZE, %g7 + sub %o0, %o1, %g3 +1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 + ldda [%o1] ASI_BLK_P, %f0 + stda %f0, [%o1 + %g3] ASI_BLK_P + add %o1, 64, %o1 + bne,pt %xcc, 1b + prefetch [%o1 + 0x40], #one_read + membar #Sync + VISExitHalf + retl + nop + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_pageops + .type niagara2_patch_pageops,#function +niagara2_patch_pageops: + NG_DO_PATCH(copy_user_page, NG2copy_user_page) + NG_DO_PATCH(_clear_page, NGclear_page) + NG_DO_PATCH(clear_user_page, NGclear_user_page) + retl + nop + .size niagara2_patch_pageops,.-niagara2_patch_pageops --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NGmemcpy.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NGmemcpy.S @@ -1,6 +1,6 @@ /* NGmemcpy.S: Niagara optimized memcpy. * - * Copyright (C) 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) */ #ifdef __KERNEL__ @@ -16,6 +16,12 @@ wr %g0, ASI_PNF, %asi #endif +#ifdef __sparc_v9__ +#define SAVE_AMOUNT 128 +#else +#define SAVE_AMOUNT 64 +#endif + #ifndef STORE_ASI #define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P #endif @@ -50,7 +56,11 @@ #endif #ifndef STORE_INIT +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA #define STORE_INIT(src,addr) stxa src, [addr] %asi +#else +#define STORE_INIT(src,addr) stx src, [addr + 0x00] +#endif #endif #ifndef FUNC_NAME @@ -73,18 +83,19 @@ .globl FUNC_NAME .type FUNC_NAME,#function -FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ - srlx %o2, 31, %g2 +FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ + PREAMBLE + save %sp, -SAVE_AMOUNT, %sp + srlx %i2, 31, %g2 cmp %g2, 0 tne %xcc, 5 - PREAMBLE - mov %o0, GLOBAL_SPARE - cmp %o2, 0 + mov %i0, %o0 + cmp %i2, 0 be,pn %XCC, 85f - or %o0, %o1, %o3 - cmp %o2, 16 + or %o0, %i1, %i3 + cmp %i2, 16 blu,a,pn %XCC, 80f - or %o3, %o2, %o3 + or %i3, %i2, %i3 /* 2 blocks (128 bytes) is the minimum we can do the block * copy with. We need to ensure that we'll iterate at least @@ -93,31 +104,31 @@ * to (64 - 1) bytes from the length before we perform the * block copy loop. */ - cmp %o2, (2 * 64) + cmp %i2, (2 * 64) blu,pt %XCC, 70f - andcc %o3, 0x7, %g0 + andcc %i3, 0x7, %g0 /* %o0: dst - * %o1: src - * %o2: len (known to be >= 128) + * %i1: src + * %i2: len (known to be >= 128) * - * The block copy loops will use %o4/%o5,%g2/%g3 as + * The block copy loops will use %i4/%i5,%g2/%g3 as * temporaries while copying the data. */ - LOAD(prefetch, %o1, #one_read) + LOAD(prefetch, %i1, #one_read) wr %g0, STORE_ASI, %asi /* Align destination on 64-byte boundary. */ - andcc %o0, (64 - 1), %o4 + andcc %o0, (64 - 1), %i4 be,pt %XCC, 2f - sub %o4, 64, %o4 - sub %g0, %o4, %o4 ! bytes to align dst - sub %o2, %o4, %o2 -1: subcc %o4, 1, %o4 - EX_LD(LOAD(ldub, %o1, %g1)) + sub %i4, 64, %i4 + sub %g0, %i4, %i4 ! bytes to align dst + sub %i2, %i4, %i2 +1: subcc %i4, 1, %i4 + EX_LD(LOAD(ldub, %i1, %g1)) EX_ST(STORE(stb, %g1, %o0)) - add %o1, 1, %o1 + add %i1, 1, %i1 bne,pt %XCC, 1b add %o0, 1, %o0 @@ -136,111 +147,155 @@ * aligned store data at a time, this is easy to ensure. */ 2: - andcc %o1, (16 - 1), %o4 - andn %o2, (64 - 1), %g1 ! block copy loop iterator - sub %o2, %g1, %o2 ! final sub-block copy bytes + andcc %i1, (16 - 1), %i4 + andn %i2, (64 - 1), %g1 ! block copy loop iterator be,pt %XCC, 50f - cmp %o4, 8 - be,a,pt %XCC, 10f - sub %o1, 0x8, %o1 + sub %i2, %g1, %i2 ! final sub-block copy bytes + + cmp %i4, 8 + be,pt %XCC, 10f + sub %i1, %i4, %i1 /* Neither 8-byte nor 16-byte aligned, shift and mask. */ - mov %g1, %o4 - and %o1, 0x7, %g1 - sll %g1, 3, %g1 - mov 64, %o3 - andn %o1, 0x7, %o1 - EX_LD(LOAD(ldx, %o1, %g2)) - sub %o3, %g1, %o3 - sllx %g2, %g1, %g2 + and %i4, 0x7, GLOBAL_SPARE + sll GLOBAL_SPARE, 3, GLOBAL_SPARE + mov 64, %i5 + EX_LD(LOAD_TWIN(%i1, %g2, %g3)) + sub %i5, GLOBAL_SPARE, %i5 + mov 16, %o4 + mov 32, %o5 + mov 48, %o7 + mov 64, %i3 -#define SWIVEL_ONE_DWORD(SRC, TMP1, TMP2, PRE_VAL, PRE_SHIFT, POST_SHIFT, DST)\ - EX_LD(LOAD(ldx, SRC, TMP1)); \ - srlx TMP1, PRE_SHIFT, TMP2; \ - or TMP2, PRE_VAL, TMP2; \ - EX_ST(STORE_INIT(TMP2, DST)); \ - sllx TMP1, POST_SHIFT, PRE_VAL; - -1: add %o1, 0x8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x00) - add %o1, 0x8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x08) - add %o1, 0x8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x10) - add %o1, 0x8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x18) - add %o1, 32, %o1 - LOAD(prefetch, %o1, #one_read) - sub %o1, 32 - 8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x20) - add %o1, 8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x28) - add %o1, 8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x30) - add %o1, 8, %o1 - SWIVEL_ONE_DWORD(%o1, %g3, %o5, %g2, %o3, %g1, %o0 + 0x38) - subcc %o4, 64, %o4 - bne,pt %XCC, 1b + bg,pn %XCC, 9f + nop + +#define MIX_THREE_WORDS(WORD1, WORD2, WORD3, PRE_SHIFT, POST_SHIFT, TMP) \ + sllx WORD1, POST_SHIFT, WORD1; \ + srlx WORD2, PRE_SHIFT, TMP; \ + sllx WORD2, POST_SHIFT, WORD2; \ + or WORD1, TMP, WORD1; \ + srlx WORD3, PRE_SHIFT, TMP; \ + or WORD2, TMP, WORD2; + +8: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3)) + MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) + LOAD(prefetch, %i1 + %i3, #one_read) + + EX_ST(STORE_INIT(%g2, %o0 + 0x00)) + EX_ST(STORE_INIT(%g3, %o0 + 0x08)) + + EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3)) + MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%o2, %o0 + 0x10)) + EX_ST(STORE_INIT(%o3, %o0 + 0x18)) + + EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) + MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%g2, %o0 + 0x20)) + EX_ST(STORE_INIT(%g3, %o0 + 0x28)) + + EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3)) + add %i1, 64, %i1 + MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%o2, %o0 + 0x30)) + EX_ST(STORE_INIT(%o3, %o0 + 0x38)) + + subcc %g1, 64, %g1 + bne,pt %XCC, 8b add %o0, 64, %o0 -#undef SWIVEL_ONE_DWORD + ba,pt %XCC, 60f + add %i1, %i4, %i1 + +9: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3)) + MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) + LOAD(prefetch, %i1 + %i3, #one_read) + + EX_ST(STORE_INIT(%g3, %o0 + 0x00)) + EX_ST(STORE_INIT(%o2, %o0 + 0x08)) + + EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3)) + MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%o3, %o0 + 0x10)) + EX_ST(STORE_INIT(%g2, %o0 + 0x18)) + + EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) + MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%g3, %o0 + 0x20)) + EX_ST(STORE_INIT(%o2, %o0 + 0x28)) + + EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3)) + add %i1, 64, %i1 + MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) + + EX_ST(STORE_INIT(%o3, %o0 + 0x30)) + EX_ST(STORE_INIT(%g2, %o0 + 0x38)) + + subcc %g1, 64, %g1 + bne,pt %XCC, 9b + add %o0, 64, %o0 - srl %g1, 3, %g1 ba,pt %XCC, 60f - add %o1, %g1, %o1 + add %i1, %i4, %i1 10: /* Destination is 64-byte aligned, source was only 8-byte * aligned but it has been subtracted by 8 and we perform * one twin load ahead, then add 8 back into source when * we finish the loop. */ - EX_LD(LOAD_TWIN(%o1, %o4, %o5)) -1: add %o1, 16, %o1 - EX_LD(LOAD_TWIN(%o1, %g2, %g3)) - add %o1, 16 + 32, %o1 - LOAD(prefetch, %o1, #one_read) - sub %o1, 32, %o1 + EX_LD(LOAD_TWIN(%i1, %o4, %o5)) + mov 16, %o7 + mov 32, %g2 + mov 48, %g3 + mov 64, %o1 +1: EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) + LOAD(prefetch, %i1 + %o1, #one_read) EX_ST(STORE_INIT(%o5, %o0 + 0x00)) ! initializes cache line - EX_ST(STORE_INIT(%g2, %o0 + 0x08)) - EX_LD(LOAD_TWIN(%o1, %o4, %o5)) - add %o1, 16, %o1 - EX_ST(STORE_INIT(%g3, %o0 + 0x10)) + EX_ST(STORE_INIT(%o2, %o0 + 0x08)) + EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5)) + EX_ST(STORE_INIT(%o3, %o0 + 0x10)) EX_ST(STORE_INIT(%o4, %o0 + 0x18)) - EX_LD(LOAD_TWIN(%o1, %g2, %g3)) - add %o1, 16, %o1 + EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3)) EX_ST(STORE_INIT(%o5, %o0 + 0x20)) - EX_ST(STORE_INIT(%g2, %o0 + 0x28)) - EX_LD(LOAD_TWIN(%o1, %o4, %o5)) - EX_ST(STORE_INIT(%g3, %o0 + 0x30)) + EX_ST(STORE_INIT(%o2, %o0 + 0x28)) + EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5)) + add %i1, 64, %i1 + EX_ST(STORE_INIT(%o3, %o0 + 0x30)) EX_ST(STORE_INIT(%o4, %o0 + 0x38)) subcc %g1, 64, %g1 bne,pt %XCC, 1b add %o0, 64, %o0 ba,pt %XCC, 60f - add %o1, 0x8, %o1 + add %i1, 0x8, %i1 50: /* Destination is 64-byte aligned, and source is 16-byte * aligned. */ -1: EX_LD(LOAD_TWIN(%o1, %o4, %o5)) - add %o1, 16, %o1 - EX_LD(LOAD_TWIN(%o1, %g2, %g3)) - add %o1, 16 + 32, %o1 - LOAD(prefetch, %o1, #one_read) - sub %o1, 32, %o1 + mov 16, %o7 + mov 32, %g2 + mov 48, %g3 + mov 64, %o1 +1: EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5)) + EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) + LOAD(prefetch, %i1 + %o1, #one_read) EX_ST(STORE_INIT(%o4, %o0 + 0x00)) ! initializes cache line EX_ST(STORE_INIT(%o5, %o0 + 0x08)) - EX_LD(LOAD_TWIN(%o1, %o4, %o5)) - add %o1, 16, %o1 - EX_ST(STORE_INIT(%g2, %o0 + 0x10)) - EX_ST(STORE_INIT(%g3, %o0 + 0x18)) - EX_LD(LOAD_TWIN(%o1, %g2, %g3)) - add %o1, 16, %o1 + EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5)) + EX_ST(STORE_INIT(%o2, %o0 + 0x10)) + EX_ST(STORE_INIT(%o3, %o0 + 0x18)) + EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3)) + add %i1, 64, %i1 EX_ST(STORE_INIT(%o4, %o0 + 0x20)) EX_ST(STORE_INIT(%o5, %o0 + 0x28)) - EX_ST(STORE_INIT(%g2, %o0 + 0x30)) - EX_ST(STORE_INIT(%g3, %o0 + 0x38)) + EX_ST(STORE_INIT(%o2, %o0 + 0x30)) + EX_ST(STORE_INIT(%o3, %o0 + 0x38)) subcc %g1, 64, %g1 bne,pt %XCC, 1b add %o0, 64, %o0 @@ -249,47 +304,47 @@ 60: membar #Sync - /* %o2 contains any final bytes still needed to be copied + /* %i2 contains any final bytes still needed to be copied * over. If anything is left, we copy it one byte at a time. */ - RESTORE_ASI(%o3) - brz,pt %o2, 85f - sub %o0, %o1, %o3 + RESTORE_ASI(%i3) + brz,pt %i2, 85f + sub %o0, %i1, %i3 ba,a,pt %XCC, 90f .align 64 70: /* 16 < len <= 64 */ bne,pn %XCC, 75f - sub %o0, %o1, %o3 + sub %o0, %i1, %i3 72: - andn %o2, 0xf, %o4 - and %o2, 0xf, %o2 -1: subcc %o4, 0x10, %o4 - EX_LD(LOAD(ldx, %o1, %o5)) - add %o1, 0x08, %o1 - EX_LD(LOAD(ldx, %o1, %g1)) - sub %o1, 0x08, %o1 - EX_ST(STORE(stx, %o5, %o1 + %o3)) - add %o1, 0x8, %o1 - EX_ST(STORE(stx, %g1, %o1 + %o3)) + andn %i2, 0xf, %i4 + and %i2, 0xf, %i2 +1: subcc %i4, 0x10, %i4 + EX_LD(LOAD(ldx, %i1, %o4)) + add %i1, 0x08, %i1 + EX_LD(LOAD(ldx, %i1, %g1)) + sub %i1, 0x08, %i1 + EX_ST(STORE(stx, %o4, %i1 + %i3)) + add %i1, 0x8, %i1 + EX_ST(STORE(stx, %g1, %i1 + %i3)) bgu,pt %XCC, 1b - add %o1, 0x8, %o1 -73: andcc %o2, 0x8, %g0 + add %i1, 0x8, %i1 +73: andcc %i2, 0x8, %g0 be,pt %XCC, 1f nop - sub %o2, 0x8, %o2 - EX_LD(LOAD(ldx, %o1, %o5)) - EX_ST(STORE(stx, %o5, %o1 + %o3)) - add %o1, 0x8, %o1 -1: andcc %o2, 0x4, %g0 + sub %i2, 0x8, %i2 + EX_LD(LOAD(ldx, %i1, %o4)) + EX_ST(STORE(stx, %o4, %i1 + %i3)) + add %i1, 0x8, %i1 +1: andcc %i2, 0x4, %g0 be,pt %XCC, 1f nop - sub %o2, 0x4, %o2 - EX_LD(LOAD(lduw, %o1, %o5)) - EX_ST(STORE(stw, %o5, %o1 + %o3)) - add %o1, 0x4, %o1 -1: cmp %o2, 0 + sub %i2, 0x4, %i2 + EX_LD(LOAD(lduw, %i1, %i5)) + EX_ST(STORE(stw, %i5, %i1 + %i3)) + add %i1, 0x4, %i1 +1: cmp %i2, 0 be,pt %XCC, 85f nop ba,pt %xcc, 90f @@ -300,71 +355,71 @@ sub %g1, 0x8, %g1 be,pn %icc, 2f sub %g0, %g1, %g1 - sub %o2, %g1, %o2 + sub %i2, %g1, %i2 1: subcc %g1, 1, %g1 - EX_LD(LOAD(ldub, %o1, %o5)) - EX_ST(STORE(stb, %o5, %o1 + %o3)) + EX_LD(LOAD(ldub, %i1, %i5)) + EX_ST(STORE(stb, %i5, %i1 + %i3)) bgu,pt %icc, 1b - add %o1, 1, %o1 + add %i1, 1, %i1 -2: add %o1, %o3, %o0 - andcc %o1, 0x7, %g1 +2: add %i1, %i3, %o0 + andcc %i1, 0x7, %g1 bne,pt %icc, 8f sll %g1, 3, %g1 - cmp %o2, 16 + cmp %i2, 16 bgeu,pt %icc, 72b nop ba,a,pt %xcc, 73b -8: mov 64, %o3 - andn %o1, 0x7, %o1 - EX_LD(LOAD(ldx, %o1, %g2)) - sub %o3, %g1, %o3 - andn %o2, 0x7, %o4 +8: mov 64, %i3 + andn %i1, 0x7, %i1 + EX_LD(LOAD(ldx, %i1, %g2)) + sub %i3, %g1, %i3 + andn %i2, 0x7, %i4 sllx %g2, %g1, %g2 -1: add %o1, 0x8, %o1 - EX_LD(LOAD(ldx, %o1, %g3)) - subcc %o4, 0x8, %o4 - srlx %g3, %o3, %o5 - or %o5, %g2, %o5 - EX_ST(STORE(stx, %o5, %o0)) +1: add %i1, 0x8, %i1 + EX_LD(LOAD(ldx, %i1, %g3)) + subcc %i4, 0x8, %i4 + srlx %g3, %i3, %i5 + or %i5, %g2, %i5 + EX_ST(STORE(stx, %i5, %o0)) add %o0, 0x8, %o0 bgu,pt %icc, 1b sllx %g3, %g1, %g2 srl %g1, 3, %g1 - andcc %o2, 0x7, %o2 + andcc %i2, 0x7, %i2 be,pn %icc, 85f - add %o1, %g1, %o1 + add %i1, %g1, %i1 ba,pt %xcc, 90f - sub %o0, %o1, %o3 + sub %o0, %i1, %i3 .align 64 80: /* 0 < len <= 16 */ - andcc %o3, 0x3, %g0 + andcc %i3, 0x3, %g0 bne,pn %XCC, 90f - sub %o0, %o1, %o3 + sub %o0, %i1, %i3 1: - subcc %o2, 4, %o2 - EX_LD(LOAD(lduw, %o1, %g1)) - EX_ST(STORE(stw, %g1, %o1 + %o3)) + subcc %i2, 4, %i2 + EX_LD(LOAD(lduw, %i1, %g1)) + EX_ST(STORE(stw, %g1, %i1 + %i3)) bgu,pt %XCC, 1b - add %o1, 4, %o1 + add %i1, 4, %i1 -85: retl - mov EX_RETVAL(GLOBAL_SPARE), %o0 +85: ret + restore EX_RETVAL(%i0), %g0, %o0 .align 32 90: - subcc %o2, 1, %o2 - EX_LD(LOAD(ldub, %o1, %g1)) - EX_ST(STORE(stb, %g1, %o1 + %o3)) + subcc %i2, 1, %i2 + EX_LD(LOAD(ldub, %i1, %g1)) + EX_ST(STORE(stb, %g1, %i1 + %i3)) bgu,pt %XCC, 90b - add %o1, 1, %o1 - retl - mov EX_RETVAL(GLOBAL_SPARE), %o0 + add %i1, 1, %i1 + ret + restore EX_RETVAL(%i0), %g0, %o0 .size FUNC_NAME, .-FUNC_NAME --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENcopy_to_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENcopy_to_user.S @@ -0,0 +1,38 @@ +/* GENcopy_to_user.S: Generic sparc64 copy to userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_ST(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#define FUNC_NAME GENcopy_to_user +#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "GENmemcpy.S" --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NGcopy_from_user.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NGcopy_from_user.S @@ -1,6 +1,6 @@ /* NGcopy_from_user.S: Niagara optimized copy from userspace. * - * Copyright (C) 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) */ #define EX_LD(x) \ @@ -8,8 +8,8 @@ .section .fixup; \ .align 4; \ 99: wr %g0, ASI_AIUS, %asi;\ - retl; \ - mov 1, %o0; \ + ret; \ + restore %g0, 1, %o0; \ .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ @@ -24,7 +24,7 @@ #define LOAD(type,addr,dest) type##a [addr] ASI_AIUS, dest #define LOAD_TWIN(addr_reg,dest0,dest1) \ ldda [addr_reg] ASI_BLK_INIT_QUAD_LDD_AIUS, dest0 -#define EX_RETVAL(x) 0 +#define EX_RETVAL(x) %g0 #ifdef __KERNEL__ #define PREAMBLE \ --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NG2patch.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NG2patch.S @@ -0,0 +1,33 @@ +/* NG2patch.S: Patch Ultra-I routines with Niagara-2 variant. + * + * Copyright (C) 2007 David S. Miller + */ + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_copyops + .type niagara2_patch_copyops,#function +niagara2_patch_copyops: + NG_DO_PATCH(memcpy, NG2memcpy) + NG_DO_PATCH(___copy_from_user, NG2copy_from_user) + NG_DO_PATCH(___copy_to_user, NG2copy_to_user) + retl + nop + .size niagara2_patch_copyops,.-niagara2_patch_copyops --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENbzero.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENbzero.S @@ -0,0 +1,160 @@ +/* GENbzero.S: Generic sparc64 memset/clear_user. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ +#include + +#define EX_ST(x,y) \ +98: x,y; \ + .section .fixup; \ + .align 4; \ +99: retl; \ + mov %o1, %o0; \ + .section __ex_table; \ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + + .align 32 + .text + + .globl GENmemset + .type GENmemset, #function +GENmemset: /* %o0=buf, %o1=pat, %o2=len */ + and %o1, 0xff, %o3 + mov %o2, %o1 + sllx %o3, 8, %g1 + or %g1, %o3, %o2 + sllx %o2, 16, %g1 + or %g1, %o2, %o2 + sllx %o2, 32, %g1 + ba,pt %xcc, 1f + or %g1, %o2, %o2 + + .globl GENbzero + .type GENbzero, #function +GENbzero: + clr %o2 +1: brz,pn %o1, GENbzero_return + mov %o0, %o3 + + /* %o5: saved %asi, restored at GENbzero_done + * %o4: store %asi to use + */ + rd %asi, %o5 + mov ASI_P, %o4 + wr %o4, 0x0, %asi + +GENbzero_from_clear_user: + cmp %o1, 15 + bl,pn %icc, GENbzero_tiny + andcc %o0, 0x7, %g1 + be,pt %xcc, 2f + mov 8, %g2 + sub %g2, %g1, %g1 + sub %o1, %g1, %o1 +1: EX_ST(stba %o2, [%o0 + 0x00] %asi) + subcc %g1, 1, %g1 + bne,pt %xcc, 1b + add %o0, 1, %o0 +2: cmp %o1, 128 + bl,pn %icc, GENbzero_medium + andcc %o0, (64 - 1), %g1 + be,pt %xcc, GENbzero_pre_loop + mov 64, %g2 + sub %g2, %g1, %g1 + sub %o1, %g1, %o1 +1: EX_ST(stxa %o2, [%o0 + 0x00] %asi) + subcc %g1, 8, %g1 + bne,pt %xcc, 1b + add %o0, 8, %o0 + +GENbzero_pre_loop: + andn %o1, (64 - 1), %g1 + sub %o1, %g1, %o1 +GENbzero_loop: + EX_ST(stxa %o2, [%o0 + 0x00] %asi) + EX_ST(stxa %o2, [%o0 + 0x08] %asi) + EX_ST(stxa %o2, [%o0 + 0x10] %asi) + EX_ST(stxa %o2, [%o0 + 0x18] %asi) + EX_ST(stxa %o2, [%o0 + 0x20] %asi) + EX_ST(stxa %o2, [%o0 + 0x28] %asi) + EX_ST(stxa %o2, [%o0 + 0x30] %asi) + EX_ST(stxa %o2, [%o0 + 0x38] %asi) + subcc %g1, 64, %g1 + bne,pt %xcc, GENbzero_loop + add %o0, 64, %o0 + + membar #Sync + wr %o4, 0x0, %asi + brz,pn %o1, GENbzero_done +GENbzero_medium: + andncc %o1, 0x7, %g1 + be,pn %xcc, 2f + sub %o1, %g1, %o1 +1: EX_ST(stxa %o2, [%o0 + 0x00] %asi) + subcc %g1, 8, %g1 + bne,pt %xcc, 1b + add %o0, 8, %o0 +2: brz,pt %o1, GENbzero_done + nop + +GENbzero_tiny: +1: EX_ST(stba %o2, [%o0 + 0x00] %asi) + subcc %o1, 1, %o1 + bne,pt %icc, 1b + add %o0, 1, %o0 + + /* fallthrough */ + +GENbzero_done: + wr %o5, 0x0, %asi + +GENbzero_return: + retl + mov %o3, %o0 + .size GENbzero, .-GENbzero + .size GENmemset, .-GENmemset + + .globl GENclear_user + .type GENclear_user, #function +GENclear_user: /* %o0=buf, %o1=len */ + rd %asi, %o5 + brz,pn %o1, GENbzero_done + clr %o3 + cmp %o5, ASI_AIUS + bne,pn %icc, GENbzero + clr %o2 + ba,pt %xcc, GENbzero_from_clear_user + mov ASI_AIUS, %o4 + .size GENclear_user, .-GENclear_user + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define GEN_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl generic_patch_bzero + .type generic_patch_bzero,#function +generic_patch_bzero: + GEN_DO_PATCH(memset, GENmemset) + GEN_DO_PATCH(__bzero, GENbzero) + GEN_DO_PATCH(__clear_user, GENclear_user) + retl + nop + .size generic_patch_bzero,.-generic_patch_bzero --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NG2memcpy.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NG2memcpy.S @@ -0,0 +1,520 @@ +/* NG2memcpy.S: Niagara-2 optimized memcpy. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#ifdef __KERNEL__ +#include +#include +#define GLOBAL_SPARE %g7 +#else +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 +#define FPRS_FEF 0x04 +#ifdef MEMCPY_DEBUG +#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs; \ + clr %g1; clr %g2; clr %g3; subcc %g0, %g0, %g0; +#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs +#else +#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs +#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs +#endif +#define GLOBAL_SPARE %g5 +#endif + +#ifndef STORE_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P +#else +#define STORE_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef EX_LD +#define EX_LD(x) x +#endif + +#ifndef EX_ST +#define EX_ST(x) x +#endif + +#ifndef EX_RETVAL +#define EX_RETVAL(x) x +#endif + +#ifndef LOAD +#define LOAD(type,addr,dest) type [addr], dest +#endif + +#ifndef LOAD_BLK +#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_P, dest +#endif + +#ifndef STORE +#ifndef MEMCPY_DEBUG +#define STORE(type,src,addr) type src, [addr] +#else +#define STORE(type,src,addr) type##a src, [addr] 0x80 +#endif +#endif + +#ifndef STORE_BLK +#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_P +#endif + +#ifndef STORE_INIT +#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI +#endif + +#ifndef FUNC_NAME +#define FUNC_NAME NG2memcpy +#endif + +#ifndef PREAMBLE +#define PREAMBLE +#endif + +#ifndef XCC +#define XCC xcc +#endif + +#define FREG_FROB(x0, x1, x2, x3, x4, x5, x6, x7, x8) \ + faligndata %x0, %x1, %f0; \ + faligndata %x1, %x2, %f2; \ + faligndata %x2, %x3, %f4; \ + faligndata %x3, %x4, %f6; \ + faligndata %x4, %x5, %f8; \ + faligndata %x5, %x6, %f10; \ + faligndata %x6, %x7, %f12; \ + faligndata %x7, %x8, %f14; + +#define FREG_MOVE_1(x0) \ + fmovd %x0, %f0; +#define FREG_MOVE_2(x0, x1) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; +#define FREG_MOVE_3(x0, x1, x2) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; +#define FREG_MOVE_4(x0, x1, x2, x3) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; +#define FREG_MOVE_5(x0, x1, x2, x3, x4) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; +#define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; +#define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; \ + fmovd %x6, %f12; +#define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; \ + fmovd %x6, %f12; \ + fmovd %x7, %f14; +#define FREG_LOAD_1(base, x0) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)) +#define FREG_LOAD_2(base, x0, x1) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); +#define FREG_LOAD_3(base, x0, x1, x2) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); +#define FREG_LOAD_4(base, x0, x1, x2, x3) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); +#define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); +#define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); \ + EX_LD(LOAD(ldd, base + 0x28, %x5)); +#define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); \ + EX_LD(LOAD(ldd, base + 0x28, %x5)); \ + EX_LD(LOAD(ldd, base + 0x30, %x6)); + + .register %g2,#scratch + .register %g3,#scratch + + .text + .align 64 + + .globl FUNC_NAME + .type FUNC_NAME,#function +FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + srlx %o2, 31, %g2 + cmp %g2, 0 + tne %xcc, 5 + PREAMBLE + mov %o0, GLOBAL_SPARE + cmp %o2, 0 + be,pn %XCC, 85f + or %o0, %o1, %o3 + cmp %o2, 16 + blu,a,pn %XCC, 80f + or %o3, %o2, %o3 + + /* 2 blocks (128 bytes) is the minimum we can do the block + * copy with. We need to ensure that we'll iterate at least + * once in the block copy loop. At worst we'll need to align + * the destination to a 64-byte boundary which can chew up + * to (64 - 1) bytes from the length before we perform the + * block copy loop. + * + * However, the cut-off point, performance wise, is around + * 4 64-byte blocks. + */ + cmp %o2, (4 * 64) + blu,pt %XCC, 75f + andcc %o3, 0x7, %g0 + + /* %o0: dst + * %o1: src + * %o2: len (known to be >= 128) + * + * The block copy loops can use %o4, %g2, %g3 as + * temporaries while copying the data. %o5 must + * be preserved between VISEntryHalf and VISExitHalf + */ + + LOAD(prefetch, %o1 + 0x000, #one_read) + LOAD(prefetch, %o1 + 0x040, #one_read) + LOAD(prefetch, %o1 + 0x080, #one_read) + + /* Align destination on 64-byte boundary. */ + andcc %o0, (64 - 1), %o4 + be,pt %XCC, 2f + sub %o4, 64, %o4 + sub %g0, %o4, %o4 ! bytes to align dst + sub %o2, %o4, %o2 +1: subcc %o4, 1, %o4 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o0)) + add %o1, 1, %o1 + bne,pt %XCC, 1b + add %o0, 1, %o0 + +2: + /* Clobbers o5/g1/g2/g3/g7/icc/xcc. We must preserve + * o5 from here until we hit VISExitHalf. + */ + VISEntryHalf + + alignaddr %o1, %g0, %g0 + + add %o1, (64 - 1), %o4 + andn %o4, (64 - 1), %o4 + andn %o2, (64 - 1), %g1 + sub %o2, %g1, %o2 + + and %o1, (64 - 1), %g2 + add %o1, %g1, %o1 + sub %o0, %o4, %g3 + brz,pt %g2, 190f + cmp %g2, 32 + blu,a 5f + cmp %g2, 16 + cmp %g2, 48 + blu,a 4f + cmp %g2, 40 + cmp %g2, 56 + blu 170f + nop + ba,a,pt %xcc, 180f + +4: /* 32 <= low bits < 48 */ + blu 150f + nop + ba,a,pt %xcc, 160f +5: /* 0 < low bits < 32 */ + blu,a 6f + cmp %g2, 8 + cmp %g2, 24 + blu 130f + nop + ba,a,pt %xcc, 140f +6: /* 0 < low bits < 16 */ + bgeu 120f + nop + /* fall through for 0 < low bits < 8 */ +110: sub %o4, 64, %g2 + EX_LD(LOAD_BLK(%g2, %f0)) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +120: sub %o4, 56, %g2 + FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +130: sub %o4, 48, %g2 + FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_6(f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +140: sub %o4, 40, %g2 + FREG_LOAD_5(%g2, f0, f2, f4, f6, f8) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_5(f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +150: sub %o4, 32, %g2 + FREG_LOAD_4(%g2, f0, f2, f4, f6) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_4(f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +160: sub %o4, 24, %g2 + FREG_LOAD_3(%g2, f0, f2, f4) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_3(f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +170: sub %o4, 16, %g2 + FREG_LOAD_2(%g2, f0, f2) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_2(f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +180: sub %o4, 8, %g2 + FREG_LOAD_1(%g2, f0) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_1(f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +190: +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + subcc %g1, 64, %g1 + EX_LD(LOAD_BLK(%o4, %f0)) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + +195: + add %o4, %g3, %o0 + membar #Sync + + VISExitHalf + + /* %o2 contains any final bytes still needed to be copied + * over. If anything is left, we copy it one byte at a time. + */ + brz,pt %o2, 85f + sub %o0, %o1, %o3 + ba,a,pt %XCC, 90f + + .align 64 +75: /* 16 < len <= 64 */ + bne,pn %XCC, 75f + sub %o0, %o1, %o3 + +72: + andn %o2, 0xf, %o4 + and %o2, 0xf, %o2 +1: subcc %o4, 0x10, %o4 + EX_LD(LOAD(ldx, %o1, %o5)) + add %o1, 0x08, %o1 + EX_LD(LOAD(ldx, %o1, %g1)) + sub %o1, 0x08, %o1 + EX_ST(STORE(stx, %o5, %o1 + %o3)) + add %o1, 0x8, %o1 + EX_ST(STORE(stx, %g1, %o1 + %o3)) + bgu,pt %XCC, 1b + add %o1, 0x8, %o1 +73: andcc %o2, 0x8, %g0 + be,pt %XCC, 1f + nop + sub %o2, 0x8, %o2 + EX_LD(LOAD(ldx, %o1, %o5)) + EX_ST(STORE(stx, %o5, %o1 + %o3)) + add %o1, 0x8, %o1 +1: andcc %o2, 0x4, %g0 + be,pt %XCC, 1f + nop + sub %o2, 0x4, %o2 + EX_LD(LOAD(lduw, %o1, %o5)) + EX_ST(STORE(stw, %o5, %o1 + %o3)) + add %o1, 0x4, %o1 +1: cmp %o2, 0 + be,pt %XCC, 85f + nop + ba,pt %xcc, 90f + nop + +75: + andcc %o0, 0x7, %g1 + sub %g1, 0x8, %g1 + be,pn %icc, 2f + sub %g0, %g1, %g1 + sub %o2, %g1, %o2 + +1: subcc %g1, 1, %g1 + EX_LD(LOAD(ldub, %o1, %o5)) + EX_ST(STORE(stb, %o5, %o1 + %o3)) + bgu,pt %icc, 1b + add %o1, 1, %o1 + +2: add %o1, %o3, %o0 + andcc %o1, 0x7, %g1 + bne,pt %icc, 8f + sll %g1, 3, %g1 + + cmp %o2, 16 + bgeu,pt %icc, 72b + nop + ba,a,pt %xcc, 73b + +8: mov 64, %o3 + andn %o1, 0x7, %o1 + EX_LD(LOAD(ldx, %o1, %g2)) + sub %o3, %g1, %o3 + andn %o2, 0x7, %o4 + sllx %g2, %g1, %g2 +1: add %o1, 0x8, %o1 + EX_LD(LOAD(ldx, %o1, %g3)) + subcc %o4, 0x8, %o4 + srlx %g3, %o3, %o5 + or %o5, %g2, %o5 + EX_ST(STORE(stx, %o5, %o0)) + add %o0, 0x8, %o0 + bgu,pt %icc, 1b + sllx %g3, %g1, %g2 + + srl %g1, 3, %g1 + andcc %o2, 0x7, %o2 + be,pn %icc, 85f + add %o1, %g1, %o1 + ba,pt %xcc, 90f + sub %o0, %o1, %o3 + + .align 64 +80: /* 0 < len <= 16 */ + andcc %o3, 0x3, %g0 + bne,pn %XCC, 90f + sub %o0, %o1, %o3 + +1: + subcc %o2, 4, %o2 + EX_LD(LOAD(lduw, %o1, %g1)) + EX_ST(STORE(stw, %g1, %o1 + %o3)) + bgu,pt %XCC, 1b + add %o1, 4, %o1 + +85: retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .align 32 +90: + subcc %o2, 1, %o2 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o1 + %o3)) + bgu,pt %XCC, 90b + add %o1, 1, %o1 + retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .size FUNC_NAME, .-FUNC_NAME --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENpage.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENpage.S @@ -0,0 +1,77 @@ +/* GENpage.S: Generic clear and copy page. + * + * Copyright (C) 2007 (davem@davemloft.net) + */ +#include + + .text + .align 32 + +GENcopy_user_page: + set PAGE_SIZE, %g7 +1: ldx [%o1 + 0x00], %o2 + ldx [%o1 + 0x08], %o3 + ldx [%o1 + 0x10], %o4 + ldx [%o1 + 0x18], %o5 + stx %o2, [%o0 + 0x00] + stx %o3, [%o0 + 0x08] + stx %o4, [%o0 + 0x10] + stx %o5, [%o0 + 0x18] + ldx [%o1 + 0x20], %o2 + ldx [%o1 + 0x28], %o3 + ldx [%o1 + 0x30], %o4 + ldx [%o1 + 0x38], %o5 + stx %o2, [%o0 + 0x20] + stx %o3, [%o0 + 0x28] + stx %o4, [%o0 + 0x30] + stx %o5, [%o0 + 0x38] + subcc %g7, 64, %g7 + add %o1, 64, %o1 + bne,pt %xcc, 1b + add %o0, 64, %o0 + retl + nop + +GENclear_page: +GENclear_user_page: + set PAGE_SIZE, %g7 +1: stx %g0, [%o0 + 0x00] + stx %g0, [%o0 + 0x08] + stx %g0, [%o0 + 0x10] + stx %g0, [%o0 + 0x18] + stx %g0, [%o0 + 0x20] + stx %g0, [%o0 + 0x28] + stx %g0, [%o0 + 0x30] + stx %g0, [%o0 + 0x38] + subcc %g7, 64, %g7 + bne,pt %xcc, 1b + add %o0, 64, %o0 + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define GEN_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl generic_patch_pageops + .type generic_patch_pageops,#function +generic_patch_pageops: + GEN_DO_PATCH(copy_user_page, GENcopy_user_page) + GEN_DO_PATCH(_clear_page, GENclear_page) + GEN_DO_PATCH(clear_user_page, GENclear_user_page) + retl + nop + .size generic_patch_pageops,.-generic_patch_pageops --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/GENmemcpy.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/GENmemcpy.S @@ -0,0 +1,121 @@ +/* GENmemcpy.S: Generic sparc64 memcpy. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#ifdef __KERNEL__ +#define GLOBAL_SPARE %g7 +#else +#define GLOBAL_SPARE %g5 +#endif + +#ifndef EX_LD +#define EX_LD(x) x +#endif + +#ifndef EX_ST +#define EX_ST(x) x +#endif + +#ifndef EX_RETVAL +#define EX_RETVAL(x) x +#endif + +#ifndef LOAD +#define LOAD(type,addr,dest) type [addr], dest +#endif + +#ifndef STORE +#define STORE(type,src,addr) type src, [addr] +#endif + +#ifndef FUNC_NAME +#define FUNC_NAME GENmemcpy +#endif + +#ifndef PREAMBLE +#define PREAMBLE +#endif + +#ifndef XCC +#define XCC xcc +#endif + + .register %g2,#scratch + .register %g3,#scratch + + .text + .align 64 + + .globl FUNC_NAME + .type FUNC_NAME,#function +FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + srlx %o2, 31, %g2 + cmp %g2, 0 + tne %XCC, 5 + PREAMBLE + mov %o0, GLOBAL_SPARE + + cmp %o2, 0 + be,pn %XCC, 85f + or %o0, %o1, %o3 + cmp %o2, 16 + blu,a,pn %XCC, 80f + or %o3, %o2, %o3 + + xor %o0, %o1, %o4 + andcc %o4, 0x7, %g0 + bne,a,pn %XCC, 90f + sub %o0, %o1, %o3 + + and %o0, 0x7, %o4 + sub %o4, 0x8, %o4 + sub %g0, %o4, %o4 + sub %o2, %o4, %o2 +1: subcc %o4, 1, %o4 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o0)) + add %o1, 1, %o1 + bne,pt %XCC, 1b + add %o0, 1, %o0 + + andn %o2, 0x7, %g1 + sub %o2, %g1, %o2 +1: subcc %g1, 0x8, %g1 + EX_LD(LOAD(ldx, %o1, %g2)) + EX_ST(STORE(stx, %g2, %o0)) + add %o1, 0x8, %o1 + bne,pt %XCC, 1b + add %o0, 0x8, %o0 + + brz,pt %o2, 85f + sub %o0, %o1, %o3 + ba,a,pt %XCC, 90f + + .align 64 +80: /* 0 < len <= 16 */ + andcc %o3, 0x3, %g0 + bne,pn %XCC, 90f + sub %o0, %o1, %o3 + +1: + subcc %o2, 4, %o2 + EX_LD(LOAD(lduw, %o1, %g1)) + EX_ST(STORE(stw, %g1, %o1 + %o3)) + bgu,pt %XCC, 1b + add %o1, 4, %o1 + +85: retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .align 32 +90: + subcc %o2, 1, %o2 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o1 + %o3)) + bgu,pt %XCC, 90b + add %o1, 1, %o1 + retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .size FUNC_NAME, .-FUNC_NAME --- linux-source-2.6.22-2.6.22.orig/arch/sparc64/lib/NGpage.S +++ linux-source-2.6.22-2.6.22/arch/sparc64/lib/NGpage.S @@ -45,6 +45,7 @@ retl nop + .globl NGclear_page, NGclear_user_page NGclear_page: /* %o0=dest */ NGclear_user_page: /* %o0=dest, %o1=vaddr */ mov 8, %g1 --- linux-source-2.6.22-2.6.22.orig/arch/parisc/kernel/syscall_table.S +++ linux-source-2.6.22-2.6.22/arch/parisc/kernel/syscall_table.S @@ -222,9 +222,7 @@ ENTRY_SAME(setfsgid) /* I think this might work */ ENTRY_SAME(llseek) /* 140 */ - /* struct linux_dirent has longs, like 'unsigned long d_ino' which - * almost definitely should be 'ino_t d_ino' but it's too late now */ - ENTRY_DIFF(getdents) + ENTRY_COMP(getdents) /* it is POSSIBLE that select will be OK because even though fd_set * contains longs, the macros and sizes are clever. */ ENTRY_COMP(select) --- linux-source-2.6.22-2.6.22.orig/arch/parisc/kernel/sys_parisc32.c +++ linux-source-2.6.22-2.6.22/arch/parisc/kernel/sys_parisc32.c @@ -285,147 +285,6 @@ return err; } -struct linux32_dirent { - u32 d_ino; - compat_off_t d_off; - u16 d_reclen; - char d_name[1]; -}; - -struct old_linux32_dirent { - u32 d_ino; - u32 d_offset; - u16 d_namlen; - char d_name[1]; -}; - -struct getdents32_callback { - struct linux32_dirent __user * current_dir; - struct linux32_dirent __user * previous; - int count; - int error; -}; - -struct readdir32_callback { - struct old_linux32_dirent __user * dirent; - int count; -}; - -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -static int filldir32 (void *__buf, const char *name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) -{ - struct linux32_dirent __user * dirent; - struct getdents32_callback * buf = (struct getdents32_callback *) __buf; - int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, 4); - u32 d_ino; - - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - dirent = buf->previous; - if (dirent) - put_user(offset, &dirent->d_off); - dirent = buf->current_dir; - buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); - put_user(reclen, &dirent->d_reclen); - copy_to_user(dirent->d_name, name, namlen); - put_user(0, dirent->d_name + namlen); - dirent = ((void __user *)dirent) + reclen; - buf->current_dir = dirent; - buf->count -= reclen; - return 0; -} - -asmlinkage long -sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) -{ - struct file * file; - struct linux32_dirent __user * lastdirent; - struct getdents32_callback buf; - int error; - - error = -EFAULT; - if (!access_ok(VERIFY_WRITE, dirent, count)) - goto out; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.current_dir = (struct linux32_dirent __user *) dirent; - buf.previous = NULL; - buf.count = count; - buf.error = 0; - - error = vfs_readdir(file, filldir32, &buf); - if (error < 0) - goto out_putf; - error = buf.error; - lastdirent = buf.previous; - if (lastdirent) { - if (put_user(file->f_pos, &lastdirent->d_off)) - error = -EFAULT; - else - error = count - buf.count; - } - -out_putf: - fput(file); -out: - return error; -} - -static int fillonedir32(void * __buf, const char * name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) -{ - struct readdir32_callback * buf = (struct readdir32_callback *) __buf; - struct old_linux32_dirent __user * dirent; - u32 d_ino; - - if (buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - buf->count++; - dirent = buf->dirent; - put_user(d_ino, &dirent->d_ino); - put_user(offset, &dirent->d_offset); - put_user(namlen, &dirent->d_namlen); - copy_to_user(dirent->d_name, name, namlen); - put_user(0, dirent->d_name + namlen); - return 0; -} - -asmlinkage long -sys32_readdir (unsigned int fd, void __user * dirent, unsigned int count) -{ - int error; - struct file * file; - struct readdir32_callback buf; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.count = 0; - buf.dirent = dirent; - - error = vfs_readdir(file, fillonedir32, &buf); - if (error >= 0) - error = buf.count; - fput(file); -out: - return error; -} - /*** copied from mips64 ***/ /* * Ooo, nasty. We need here to frob 32-bit unsigned longs to --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/mm/slice.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/mm/slice.c @@ -405,6 +405,8 @@ if (len > mm->task_size) return -ENOMEM; + if (len & ((1ul << pshift) - 1)) + return -EINVAL; if (fixed && (addr & ((1ul << pshift) - 1))) return -EINVAL; if (fixed && addr > (mm->task_size - len)) --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/kernel/misc_32.S +++ linux-source-2.6.22-2.6.22/arch/powerpc/kernel/misc_32.S @@ -728,6 +728,27 @@ or r4,r4,r7 # LSW |= t2 blr +/* + * __ucmpdi2: 64-bit comparison + * + * R3/R4 has 64 bit value A + * R5/R6 has 64 bit value B + * result in R3: 0 for A < B + * 1 for A == B + * 2 for A > B + */ +_GLOBAL(__ucmpdi2) + cmplw r7,r3,r5 # compare high words + li r3,0 + blt r7,2f # a < b ... return 0 + bgt r7,1f # a > b ... return 2 + cmplw r6,r4,r6 # compare low words + blt r6,2f # a < b ... return 0 + li r3,1 + ble r6,2f # a = b ... return 1 +1: li r3,2 +2: blr + _GLOBAL(abs) srawi r4,r3,31 xor r3,r3,r4 --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/kernel/process.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/kernel/process.c @@ -83,7 +83,7 @@ */ BUG_ON(tsk != current); #endif - giveup_fpu(current); + giveup_fpu(tsk); } preempt_enable(); } @@ -143,7 +143,7 @@ #ifdef CONFIG_SMP BUG_ON(tsk != current); #endif - giveup_altivec(current); + giveup_altivec(tsk); } preempt_enable(); } @@ -182,7 +182,7 @@ #ifdef CONFIG_SMP BUG_ON(tsk != current); #endif - giveup_spe(current); + giveup_spe(tsk); } preempt_enable(); } --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/kernel/prom_parse.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/kernel/prom_parse.c @@ -24,7 +24,7 @@ /* Max address size we deal with */ #define OF_MAX_ADDR_CELLS 4 #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ - (ns) >= 0) + (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); static int __of_address_to_resource(struct device_node *dev, --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/kernel/ppc_ksyms.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/kernel/ppc_ksyms.c @@ -158,9 +158,11 @@ long long __ashrdi3(long long, int); long long __ashldi3(long long, int); long long __lshrdi3(long long, int); +int __ucmpdi2(uint64_t, uint64_t); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__ucmpdi2); #endif EXPORT_SYMBOL(memcpy); --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/chrp/setup.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/chrp/setup.c @@ -116,7 +116,7 @@ seq_printf(m, "machine\t\t: CHRP %s\n", model); /* longtrail (goldengate) stuff */ - if (!strncmp(model, "IBM,LongTrail", 13)) { + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) @@ -204,15 +204,20 @@ static void __init sio_init(void) { struct device_node *root; + const char *model; - if ((root = of_find_node_by_path("/")) && - !strncmp(of_get_property(root, "model", NULL), - "IBM,LongTrail", 13)) { + root = of_find_node_by_path("/"); + if (!root) + return; + + model = of_get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM,LongTrail", 13)) { /* logical device 0 (KBC/Keyboard) */ sio_fixup_irq("keyboard", 0, 1, 2); /* select logical device 1 (KBC/Mouse) */ sio_fixup_irq("mouse", 1, 12, 2); } + of_node_put(root); } --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -147,7 +147,6 @@ { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -75,7 +75,6 @@ { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -111,7 +111,6 @@ { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -118,7 +118,6 @@ { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; --- linux-source-2.6.22-2.6.22.orig/arch/powerpc/platforms/powermac/setup.c +++ linux-source-2.6.22-2.6.22/arch/powerpc/platforms/powermac/setup.c @@ -643,12 +643,10 @@ DMA_MODE_READ = 1; DMA_MODE_WRITE = 2; -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -#ifdef CONFIG_BLK_DEV_IDE_PMAC +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; ppc_ide_md.default_io_base = pmac_ide_get_base; -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ -#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ +#endif #endif /* CONFIG_PPC32 */ --- linux-source-2.6.22-2.6.22.orig/arch/um/drivers/ubd_kern.c +++ linux-source-2.6.22-2.6.22/arch/um/drivers/ubd_kern.c @@ -612,6 +612,8 @@ ubd_dev->fd = fd; if(ubd_dev->cow.file != NULL){ + blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); + err = -ENOMEM; ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); if(ubd_dev->cow.bitmap == NULL){ --- linux-source-2.6.22-2.6.22.orig/arch/um/os-Linux/user_syms.c +++ linux-source-2.6.22-2.6.22/arch/um/os-Linux/user_syms.c @@ -5,7 +5,8 @@ * so I *must* declare good prototypes for them and then EXPORT them. * The kernel code uses the macro defined by include/linux/string.h, * so I undef macros; the userspace code does not include that and I - * add an EXPORT for the glibc one.*/ + * add an EXPORT for the glibc one. + */ #undef strlen #undef strstr @@ -61,12 +62,18 @@ EXPORT_SYMBOL_PROTO(__xstat); EXPORT_SYMBOL_PROTO(__lxstat); EXPORT_SYMBOL_PROTO(__lxstat64); +EXPORT_SYMBOL_PROTO(__fxstat64); EXPORT_SYMBOL_PROTO(lseek); EXPORT_SYMBOL_PROTO(lseek64); EXPORT_SYMBOL_PROTO(chown); +EXPORT_SYMBOL_PROTO(fchown); EXPORT_SYMBOL_PROTO(truncate); +EXPORT_SYMBOL_PROTO(ftruncate64); EXPORT_SYMBOL_PROTO(utime); +EXPORT_SYMBOL_PROTO(utimes); +EXPORT_SYMBOL_PROTO(futimes); EXPORT_SYMBOL_PROTO(chmod); +EXPORT_SYMBOL_PROTO(fchmod); EXPORT_SYMBOL_PROTO(rename); EXPORT_SYMBOL_PROTO(__xmknod); @@ -102,14 +109,3 @@ extern long __guard __attribute__((weak)); EXPORT_SYMBOL(__guard); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ --- linux-source-2.6.22-2.6.22.orig/arch/sparc/prom/console.c +++ linux-source-2.6.22-2.6.22/arch/sparc/prom/console.c @@ -102,119 +102,3 @@ while(prom_nbputchar(c) == -1) ; return; } - -/* Query for input device type */ -enum prom_input_device -prom_query_input_device(void) -{ - unsigned long flags; - int st_p; - char propb[64]; - char *p; - int propl; - - switch(prom_vers) { - case PROM_V0: - case PROM_V2: - case PROM_SUN4: - default: - switch(*romvec->pv_stdin) { - case PROMDEV_KBD: return PROMDEV_IKBD; - case PROMDEV_TTYA: return PROMDEV_ITTYA; - case PROMDEV_TTYB: return PROMDEV_ITTYB; - default: - return PROMDEV_I_UNK; - }; - case PROM_V3: - spin_lock_irqsave(&prom_lock, flags); - st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - if(prom_node_has_property(st_p, "keyboard")) - return PROMDEV_IKBD; - if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) { - if(strncmp(propb, "keyboard", sizeof("serial")) == 0) - return PROMDEV_IKBD; - } - if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) { - if(strncmp(propb, "serial", sizeof("serial"))) - return PROMDEV_I_UNK; - } - propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb)); - if(propl > 2) { - p = propb; - while(*p) p++; p -= 2; - if(p[0] == ':') { - if(p[1] == 'a') - return PROMDEV_ITTYA; - else if(p[1] == 'b') - return PROMDEV_ITTYB; - } - } - return PROMDEV_I_UNK; - } -} - -/* Query for output device type */ - -enum prom_output_device -prom_query_output_device(void) -{ - unsigned long flags; - int st_p; - char propb[64]; - char *p; - int propl; - - switch(prom_vers) { - case PROM_V0: - case PROM_SUN4: - switch(*romvec->pv_stdin) { - case PROMDEV_SCREEN: return PROMDEV_OSCREEN; - case PROMDEV_TTYA: return PROMDEV_OTTYA; - case PROMDEV_TTYB: return PROMDEV_OTTYB; - }; - break; - case PROM_V2: - case PROM_V3: - spin_lock_irqsave(&prom_lock, flags); - st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); - if (propl == sizeof("display") && - strncmp("display", propb, sizeof("display")) == 0) - { - return PROMDEV_OSCREEN; - } - if(prom_vers == PROM_V3) { - if(propl >= 0 && - strncmp("serial", propb, sizeof("serial")) != 0) - return PROMDEV_O_UNK; - propl = prom_getproperty(prom_root_node, "stdout-path", - propb, sizeof(propb)); - if(propl == CON_SIZE_JMC && - strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0) - return PROMDEV_OTTYA; - if(propl > 2) { - p = propb; - while(*p) p++; p-= 2; - if(p[0]==':') { - if(p[1] == 'a') - return PROMDEV_OTTYA; - else if(p[1] == 'b') - return PROMDEV_OTTYB; - } - } - } else { - switch(*romvec->pv_stdin) { - case PROMDEV_TTYA: return PROMDEV_OTTYA; - case PROMDEV_TTYB: return PROMDEV_OTTYB; - }; - } - break; - default: - ; - }; - return PROMDEV_O_UNK; -} --- linux-source-2.6.22-2.6.22.orig/arch/sparc/prom/misc.c +++ linux-source-2.6.22-2.6.22/arch/sparc/prom/misc.c @@ -58,7 +58,7 @@ extern void install_linux_ticker(void); unsigned long flags; - if(!serial_console && prom_palette) + if (prom_palette) prom_palette (1); spin_lock_irqsave(&prom_lock, flags); install_obp_ticker(); @@ -69,7 +69,7 @@ #ifdef CONFIG_SUN_AUXIO set_auxio(AUXIO_LED, 0); #endif - if(!serial_console && prom_palette) + if (prom_palette) prom_palette (0); } --- linux-source-2.6.22-2.6.22.orig/arch/sparc/kernel/sys_sparc.c +++ linux-source-2.6.22-2.6.22/arch/sparc/kernel/sys_sparc.c @@ -224,8 +224,7 @@ { if (ARCH_SUN4C_SUN4 && (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) + (addr < 0xe0000000 && addr + len > 0x20000000))) return -EINVAL; /* See asm-sparc/uaccess.h */ --- linux-source-2.6.22-2.6.22.orig/arch/sparc/kernel/prom.c +++ linux-source-2.6.22-2.6.22/arch/sparc/kernel/prom.c @@ -271,6 +271,21 @@ } EXPORT_SYMBOL(of_set_property); +int of_find_in_proplist(const char *list, const char *match, int len) +{ + while (len > 0) { + int l; + + if (!strcmp(list, match)) + return 1; + l = strlen(list) + 1; + list += l; + len -= l; + } + return 0; +} +EXPORT_SYMBOL(of_find_in_proplist); + static unsigned int prom_early_allocated; static void * __init prom_early_alloc(unsigned long size) @@ -566,6 +581,135 @@ return dp; } +struct device_node *of_console_device; +EXPORT_SYMBOL(of_console_device); + +char *of_console_path; +EXPORT_SYMBOL(of_console_path); + +char *of_console_options; +EXPORT_SYMBOL(of_console_options); + +extern void restore_current(void); + +static void __init of_console_init(void) +{ + char *msg = "OF stdout device is: %s\n"; + struct device_node *dp; + unsigned long flags; + const char *type; + phandle node; + int skip, fd; + + of_console_path = prom_early_alloc(256); + + switch (prom_vers) { + case PROM_V0: + case PROM_SUN4: + skip = 0; + switch (*romvec->pv_stdout) { + case PROMDEV_SCREEN: + type = "display"; + break; + + case PROMDEV_TTYB: + skip = 1; + /* FALLTHRU */ + + case PROMDEV_TTYA: + type = "serial"; + break; + + default: + prom_printf("Invalid PROM_V0 stdout value %u\n", + *romvec->pv_stdout); + prom_halt(); + } + + for_each_node_by_type(dp, type) { + if (!skip--) + break; + } + if (!dp) { + prom_printf("Cannot find PROM_V0 console node.\n"); + prom_halt(); + } + of_console_device = dp; + + strcpy(of_console_path, dp->full_name); + if (!strcmp(type, "serial")) { + strcat(of_console_path, + (skip ? ":b" : ":a")); + } + break; + + default: + case PROM_V2: + case PROM_V3: + fd = *romvec->pv_v2bootargs.fd_stdout; + + spin_lock_irqsave(&prom_lock, flags); + node = (*romvec->pv_v2devops.v2_inst2pkg)(fd); + restore_current(); + spin_unlock_irqrestore(&prom_lock, flags); + + if (!node) { + prom_printf("Cannot resolve stdout node from " + "instance %08x.\n", fd); + prom_halt(); + } + dp = of_find_node_by_phandle(node); + type = of_get_property(dp, "device_type", NULL); + + if (!type) { + prom_printf("Console stdout lacks " + "device_type property.\n"); + prom_halt(); + } + + if (strcmp(type, "display") && strcmp(type, "serial")) { + prom_printf("Console device_type is neither display " + "nor serial.\n"); + prom_halt(); + } + + of_console_device = dp; + + if (prom_vers == PROM_V2) { + strcpy(of_console_path, dp->full_name); + switch (*romvec->pv_stdout) { + case PROMDEV_TTYA: + strcat(of_console_path, ":a"); + break; + case PROMDEV_TTYB: + strcat(of_console_path, ":b"); + break; + } + } else { + const char *path; + + dp = of_find_node_by_path("/"); + path = of_get_property(dp, "stdout-path", NULL); + if (!path) { + prom_printf("No stdout-path in root node.\n"); + prom_halt(); + } + strcpy(of_console_path, path); + } + break; + } + + of_console_options = strrchr(of_console_path, ':'); + if (of_console_options) { + of_console_options++; + if (*of_console_options == '\0') + of_console_options = NULL; + } + + prom_printf(msg, of_console_path); + printk(msg, of_console_path); +} + void __init prom_build_devicetree(void) { struct device_node **nextp; @@ -578,6 +722,8 @@ allnodes->child = build_tree(allnodes, prom_getchild(allnodes->node), &nextp); + of_console_init(); + printk("PROM: Built device tree with %u bytes of memory.\n", prom_early_allocated); } --- linux-source-2.6.22-2.6.22.orig/arch/sparc/kernel/process.c +++ linux-source-2.6.22-2.6.22/arch/sparc/kernel/process.c @@ -39,6 +39,7 @@ #include #include #include +#include #include /* @@ -150,7 +151,7 @@ local_irq_enable(); mdelay(8); local_irq_disable(); - if (!serial_console && prom_palette) + if (prom_palette) prom_palette (1); prom_halt(); panic("Halt failed!"); @@ -166,7 +167,7 @@ p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (!serial_console && prom_palette) + if (prom_palette) prom_palette (1); if (cmd) prom_reboot(cmd); @@ -179,7 +180,8 @@ void machine_power_off(void) { #ifdef CONFIG_SUN_AUXIO - if (auxio_power_register && (!serial_console || scons_pwroff)) + if (auxio_power_register && + (strcmp(of_console_device->type, "serial") || scons_pwroff)) *auxio_power_register |= AUXIO_POWER_OFF; #endif machine_halt(); --- linux-source-2.6.22-2.6.22.orig/arch/sparc/kernel/setup.c +++ linux-source-2.6.22-2.6.22/arch/sparc/kernel/setup.c @@ -146,31 +146,6 @@ } } -static void __init process_console(char *commands) -{ - serial_console = 0; - commands += 8; - /* Linux-style serial */ - if (!strncmp(commands, "ttyS", 4)) - serial_console = simple_strtoul(commands + 4, NULL, 10) + 1; - else if (!strncmp(commands, "tty", 3)) { - char c = *(commands + 3); - /* Solaris-style serial */ - if (c == 'a' || c == 'b') - serial_console = c - 'a' + 1; - /* else Linux-style fbcon, not serial */ - } -#if defined(CONFIG_PROM_CONSOLE) - if (!strncmp(commands, "prom", 4)) { - char *p; - - for (p = commands - 8; *p && *p != ' '; p++) - *p = ' '; - conswitchp = &prom_con; - } -#endif -} - static void __init boot_flags_init(char *commands) { while (*commands) { @@ -187,9 +162,7 @@ process_switch(*commands++); continue; } - if (!strncmp(commands, "console=", 8)) { - process_console(commands); - } else if (!strncmp(commands, "mem=", 4)) { + if (!strncmp(commands, "mem=", 4)) { /* * "mem=XXX[kKmM] overrides the PROM-reported * memory size. @@ -341,41 +314,6 @@ smp_setup_cpu_possible_map(); } -static int __init set_preferred_console(void) -{ - int idev, odev; - - /* The user has requested a console so this is already set up. */ - if (serial_console >= 0) - return -EBUSY; - - idev = prom_query_input_device(); - odev = prom_query_output_device(); - if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { - serial_console = 0; - } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { - serial_console = 1; - } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { - serial_console = 2; - } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) { - prom_printf("MrCoffee ttya\n"); - serial_console = 1; - } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) { - serial_console = 0; - prom_printf("MrCoffee keyboard\n"); - } else { - prom_printf("Confusing console (idev %d, odev %d)\n", - idev, odev); - serial_console = 1; - } - - if (serial_console) - return add_preferred_console("ttyS", serial_console - 1, NULL); - - return -ENODEV; -} -console_initcall(set_preferred_console); - extern char *sparc_cpu_type; extern char *sparc_fpu_type; @@ -461,7 +399,6 @@ prom_cmdline(); } -int serial_console = -1; int stop_a_enabled = 1; static int __init topology_init(void) --- linux-source-2.6.22-2.6.22.orig/arch/sparc/kernel/entry.S +++ linux-source-2.6.22-2.6.22/arch/sparc/kernel/entry.S @@ -1749,8 +1749,8 @@ __ndelay: save %sp, -STACKFRAME_SZ, %sp mov %i0, %o0 - call .umul - mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ) + call .umul ! round multiplier up so large ns ok + mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) call .umul mov %i1, %o1 ! udelay_val ba delay_continue @@ -1760,11 +1760,17 @@ __udelay: save %sp, -STACKFRAME_SZ, %sp mov %i0, %o0 - sethi %hi(0x10c6), %o1 + sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok call .umul - or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000 + or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 call .umul mov %i1, %o1 ! udelay_val + sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, + or %g0, %lo(0x028f4b62), %l0 + addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 + bcs,a 3f + add %o1, 0x01, %o1 +3: call .umul mov HZ, %o0 ! >>32 earlier for wider range --- linux-source-2.6.22-2.6.22.orig/arch/sparc/lib/memset.S +++ linux-source-2.6.22-2.6.22/arch/sparc/lib/memset.S @@ -162,7 +162,7 @@ 8: add %o0, 1, %o0 subcc %o1, 1, %o1 - bne,a 8b + bne 8b EX(stb %g3, [%o0 - 1], add %o1, 1) 0: retl --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/Makefile +++ linux-source-2.6.22-2.6.22/arch/x86_64/Makefile @@ -57,8 +57,8 @@ cflags-y += -maccumulate-outgoing-args # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/Kconfig.debug +++ linux-source-2.6.22-2.6.22/arch/x86_64/Kconfig.debug @@ -6,6 +6,12 @@ source "lib/Kconfig.debug" +config WRAPPER_PRINT + bool "Boot wrapper print" if EMBEDDED + default y + help + Enable informational output from the bootwrapper (bzImage and zImage). + config DEBUG_RODATA bool "Write protect kernel read-only data structures" depends on DEBUG_KERNEL --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/kernel/head.S +++ linux-source-2.6.22-2.6.22/arch/x86_64/kernel/head.S @@ -326,8 +326,7 @@ /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE) /* Module mapping starts here */ .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/kernel/ptrace.c +++ linux-source-2.6.22-2.6.22/arch/x86_64/kernel/ptrace.c @@ -223,10 +223,6 @@ { unsigned long tmp; - /* Some code in the 64bit emulation may not be 64bit clean. - Don't take any chances. */ - if (test_tsk_thread_flag(child, TIF_IA32)) - value &= 0xffffffff; switch (regno) { case offsetof(struct user_regs_struct,fs): if (value && (value & 3) != 3) --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/kernel/Makefile +++ linux-source-2.6.22-2.6.22/arch/x86_64/kernel/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o -obj-$(CONFIG_SERIAL_8250) += legacy_serial.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_X86_VSMP) += vsmp.o @@ -50,7 +49,6 @@ therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o bootflag-y += ../../i386/kernel/bootflag.o -legacy_serial-y += ../../i386/kernel/legacy_serial.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o topology-y += ../../i386/kernel/topology.o microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/kernel/entry.S +++ linux-source-2.6.22-2.6.22/arch/x86_64/kernel/entry.S @@ -775,7 +775,7 @@ swapgs paranoid_restore\trace: RESTORE_ALL 8 - iretq + jmp iret_label paranoid_userspace\trace: GET_THREAD_INFO(%rcx) movl threadinfo_flags(%rcx),%ebx --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/ia32/ia32entry.S +++ linux-source-2.6.22-2.6.22/arch/x86_64/ia32/ia32entry.S @@ -38,6 +38,18 @@ movq %rax,R8(%rsp) .endm + .macro LOAD_ARGS32 offset + movl \offset(%rsp),%r11d + movl \offset+8(%rsp),%r10d + movl \offset+16(%rsp),%r9d + movl \offset+24(%rsp),%r8d + movl \offset+40(%rsp),%ecx + movl \offset+48(%rsp),%edx + movl \offset+56(%rsp),%esi + movl \offset+64(%rsp),%edi + movl \offset+72(%rsp),%eax + .endm + .macro CFI_STARTPROC32 simple CFI_STARTPROC \simple CFI_UNDEFINED r8 @@ -152,7 +164,7 @@ movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST movl %ebp, %ebp /* no need to do an access_ok check here because rbp has been @@ -255,7 +267,7 @@ movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST movl RSP-ARGOFFSET(%rsp), %r8d /* no need to do an access_ok check here because r8 has been @@ -333,7 +345,7 @@ movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST jmp ia32_do_syscall END(ia32_syscall) --- linux-source-2.6.22-2.6.22.orig/arch/x86_64/boot/compressed/misc.c +++ linux-source-2.6.22-2.6.22/arch/x86_64/boot/compressed/misc.c @@ -184,8 +184,6 @@ static void *memset(void *s, int c, unsigned n); static void *memcpy(void *dest, const void *src, unsigned n); -static void putstr(const char *); - static long free_mem_ptr; static long free_mem_end_ptr; @@ -228,7 +226,8 @@ { free_mem_ptr = (long) *ptr; } - + +#ifdef CONFIG_WRAPPER_PRINT static void scroll(void) { int i; @@ -274,6 +273,9 @@ outb_p(15, vidport); outb_p(0xff & (pos >> 1), vidport+1); } +#else +#define putstr(__x) do{}while(0) +#endif /* CONFIG_WRAPPER_PRINT */ static void* memset(void* s, int c, unsigned n) { --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/events/evgpeblk.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/events/evgpeblk.c @@ -586,6 +586,10 @@ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); if (gpe_xrupt->previous) { gpe_xrupt->previous->next = gpe_xrupt->next; + } else { + /* No previous, update list head */ + + acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next; } if (gpe_xrupt->next) { --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/processor_idle.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/processor_idle.c @@ -324,6 +324,23 @@ #endif +/* + * Suspend / resume control + */ +static int acpi_idle_suspend; + +int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) +{ + acpi_idle_suspend = 1; + return 0; +} + +int acpi_processor_resume(struct acpi_device * device) +{ + acpi_idle_suspend = 0; + return 0; +} + static void acpi_processor_idle(void) { struct acpi_processor *pr = NULL; @@ -354,7 +371,7 @@ } cx = pr->power.state; - if (!cx) { + if (!cx || acpi_idle_suspend) { if (pm_idle_save) pm_idle_save(); else --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/osl.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/osl.c @@ -275,6 +275,67 @@ return AE_OK; } +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +struct acpi_table_header * acpi_find_dsdt_initrd(void) +{ + struct file *firmware_file; + mm_segment_t oldfs; + unsigned long len, len2; + struct acpi_table_header *dsdt_buffer, *ret = NULL; + struct kstat stat; + /* maybe this could be an argument on the cmd line, but let's keep it simple for now */ + char *ramfs_dsdt_name = "/DSDT.aml"; + + printk(KERN_INFO PREFIX "Looking for DSDT in initramfs... "); + + /* + * Never do this at home, only the user-space is allowed to open a file. + * The clean way would be to use the firmware loader. But this code must be run + * before there is any userspace available. So we need a static/init firmware + * infrastructure, which doesn't exist yet... + */ + if (vfs_stat(ramfs_dsdt_name, &stat) < 0) { + printk("error, file %s not found.\n", ramfs_dsdt_name); + return ret; + } + + len = stat.size; + /* check especially against empty files */ + if (len <= 4) { + printk("error file is too small, only %lu bytes.\n", len); + return ret; + } + + firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0); + if (IS_ERR(firmware_file)) { + printk("error, could not open file %s.\n", ramfs_dsdt_name); + return ret; + } + + dsdt_buffer = ACPI_ALLOCATE(len); + if (!dsdt_buffer) { + printk("error when allocating %lu bytes of memory.\n", len); + goto err; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos); + set_fs(oldfs); + if (len2 < len) { + printk("error trying to read %lu bytes from %s.\n", len, ramfs_dsdt_name); + ACPI_FREE(dsdt_buffer); + goto err; + } + + printk("successfully read %lu bytes from %s.\n", len, ramfs_dsdt_name); + ret = dsdt_buffer; +err: + filp_close(firmware_file, NULL); + return ret; +} +#endif + acpi_status acpi_os_table_override(struct acpi_table_header * existing_table, struct acpi_table_header ** new_table) @@ -282,13 +343,18 @@ if (!existing_table || !new_table) return AE_BAD_PARAMETER; + *new_table = NULL; + #ifdef CONFIG_ACPI_CUSTOM_DSDT if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; - else - *new_table = NULL; -#else - *new_table = NULL; +#endif +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD + if (strncmp(existing_table->signature, "DSDT", 4) == 0) { + struct acpi_table_header* initrd_table = acpi_find_dsdt_initrd(); + if (initrd_table) + *new_table = initrd_table; + } #endif return AE_OK; } --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/ec.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/ec.c @@ -801,8 +801,8 @@ ec->handle = handle; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", - ec->gpe, ec->command_addr, ec->data_addr)); + printk(KERN_INFO PREFIX "GPE=0x%02lx, ports=0x%2lx, 0x%2lx\n", + ec->gpe, ec->command_addr, ec->data_addr); return AE_CTRL_TERMINATE; } @@ -819,19 +819,22 @@ /* * Generate a boot ec context */ - status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); - if (ACPI_FAILURE(status)) - goto error; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); - - boot_ec->command_addr = ecdt_ptr->control.address; - boot_ec->data_addr = ecdt_ptr->data.address; - boot_ec->gpe = ecdt_ptr->gpe; - boot_ec->handle = ACPI_ROOT_OBJECT; - + if (ACPI_SUCCESS(status)) { + printk(KERN_INFO PREFIX "Found ECDT\n"); + boot_ec->command_addr = ecdt_ptr->control.address; + boot_ec->data_addr = ecdt_ptr->data.address; + boot_ec->gpe = ecdt_ptr->gpe; + boot_ec->handle = ACPI_ROOT_OBJECT; + } else { + printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); + status = acpi_get_devices(ACPI_EC_HID, ec_parse_device, + boot_ec, NULL); + if (ACPI_FAILURE(status)) + goto error; + } + ret = ec_install_handlers(boot_ec); if (!ret) { first_ec = boot_ec; --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/processor_core.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/processor_core.c @@ -93,6 +93,8 @@ .add = acpi_processor_add, .remove = acpi_processor_remove, .start = acpi_processor_start, + .suspend = acpi_processor_suspend, + .resume = acpi_processor_resume, }, }; --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/scan.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/scan.c @@ -9,6 +9,8 @@ #include #include /* for acpi_ex_eisa_id_to_string() */ +#include +#include #define _COMPONENT ACPI_BUS_COMPONENT ACPI_MODULE_NAME("scan"); @@ -1380,6 +1382,19 @@ return result; } +int acpi_method_notify_enable(char *pathname) +{ + struct acpi_namespace_node *method; + acpi_ns_get_node (ACPI_NS_ALL, pathname, 0, &method); + if (!method) + return -ENODEV; + + acpi_ns_get_attached_object(method)->method.method_flags |= AML_METHOD_NOTIFY; + return 0; +} + +EXPORT_SYMBOL (acpi_method_notify_enable); + static int __init acpi_scan_init(void) { int result; --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/toshiba_acpi.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/toshiba_acpi.c @@ -27,13 +27,28 @@ * engineering the Windows drivers * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 * Rob Miller - TV out and hotkeys help + * Daniel Silverstone - Punting of hotkeys via acpi using a thread * + * PLEASE NOTE + * + * This is an experimental version of toshiba_acpi which includes emulation + * of the original toshiba driver's /proc/toshiba and /dev/toshiba, + * allowing Toshiba userspace utilities to work. The relevant code was + * based on toshiba.c (copyright 1996-2001 Jonathan A. Buzzard) and + * incorporated into this driver with help from Gintautas Miliauskas, + * Charles Schwieters, and Christoph Burger-Scheidlin. + * + * Caveats: + * * hotkey status in /proc/toshiba is not implemented + * * to make accesses to /dev/toshiba load this driver instead of + * the original driver, you will have to modify your module + * auto-loading configuration * * TODO * */ -#define TOSHIBA_ACPI_VERSION "0.18" +#define TOSHIBA_ACPI_VERSION "0.19a-dev" #define PROC_INTERFACE_VERSION 1 #include @@ -41,12 +56,32 @@ #include #include #include +#include +#include +#include +#include +#include #include - +#include #include #include +/* Some compatibility for isa legacy interface */ +#ifndef isa_readb + +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) + +#endif + MODULE_AUTHOR("John Belmonte"); MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); MODULE_LICENSE("GPL"); @@ -216,6 +251,11 @@ static int force_fan; static int last_key_event; static int key_event_valid; +static int hotkeys_over_acpi = 1; +static int hotkeys_check_per_sec = 2; + +module_param(hotkeys_over_acpi, uint, 0400); +module_param(hotkeys_check_per_sec, uint, 0400); typedef struct _ProcItem { const char *name; @@ -443,27 +483,34 @@ u32 hci_result; u32 value; - if (!key_event_valid) { - hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); - if (hci_result == HCI_SUCCESS) { - key_event_valid = 1; - last_key_event = value; - } else if (hci_result == HCI_EMPTY) { - /* better luck next time */ - } else if (hci_result == HCI_NOT_SUPPORTED) { - /* This is a workaround for an unresolved issue on - * some machines where system events sporadically - * become disabled. */ - hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); - printk(MY_NOTICE "Re-enabled hotkeys\n"); - } else { - printk(MY_ERR "Error reading hotkey status\n"); - goto end; + if (!hotkeys_over_acpi) { + if (!key_event_valid) { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + key_event_valid = 1; + last_key_event = value; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } else { + printk(MY_ERR "Error reading hotkey status\n"); + goto end; + } } + } else { + key_event_valid = 0; + last_key_event = 0; } p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + p += sprintf(p, "hotkeys_via_acpi: %d\n", hotkeys_over_acpi); end: return p; @@ -490,6 +537,179 @@ return p; } +/* /dev/toshiba and /proc/toshiba handlers {{{ + * + * ISSUE: lots of magic numbers and mysterious code + */ + +#define TOSH_MINOR_DEV 181 +#define OLD_PROC_TOSHIBA "toshiba" + +static int +tosh_acpi_bridge(SMMRegisters* regs) +{ + acpi_status status; + + /* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */ + status = hci_raw((u32*)regs, (u32*)regs); + if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS) + return 0; + + return -EINVAL; +} + +static int +tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd, + unsigned long arg) +{ + SMMRegisters regs; + unsigned short ax,bx; + int err; + + if ((!arg) || (cmd != TOSH_SMM)) + return -EINVAL; + + if (copy_from_user(®s, (SMMRegisters*)arg, sizeof(SMMRegisters))) + return -EFAULT; + + ax = regs.eax & 0xff00; + bx = regs.ebx & 0xffff; + + /* block HCI calls to read/write memory & PCI devices */ + if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069)) + return -EINVAL; + + err = tosh_acpi_bridge(®s); + + if (copy_to_user((SMMRegisters*)arg, ®s, sizeof(SMMRegisters))) + return -EFAULT; + + return err; +} + +static int +tosh_get_machine_id(void) +{ + int id; + unsigned short bx,cx; + unsigned long address; + + id = (0x100*(int)isa_readb(0xffffe))+((int)isa_readb(0xffffa)); + + /* do we have a SCTTable machine identication number on our hands */ + if (id==0xfc2f) { + bx = 0xe6f5; /* cheat */ + /* now twiddle with our pointer a bit */ + address = 0x000f0000+bx; + cx = isa_readw(address); + address = 0x000f0009+bx+cx; + cx = isa_readw(address); + address = 0x000f000a+cx; + cx = isa_readw(address); + /* now construct our machine identification number */ + id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8); + } + + return id; +} + +static int tosh_id; +static int tosh_bios; +static int tosh_date; +static int tosh_sci; + +static struct file_operations tosh_fops = { + .owner = THIS_MODULE, + .ioctl = tosh_ioctl +}; + +static struct miscdevice tosh_device = { + TOSH_MINOR_DEV, + "toshiba", + &tosh_fops +}; + +static void +setup_tosh_info(void __iomem *bios) +{ + int major, minor; + int day, month, year; + + tosh_id = tosh_get_machine_id(); + + /* get the BIOS version */ + major = isa_readb(0xfe009)-'0'; + minor = ((isa_readb(0xfe00b)-'0')*10)+(isa_readb(0xfe00c)-'0'); + tosh_bios = (major*0x100)+minor; + + /* get the BIOS date */ + day = ((isa_readb(0xffff5)-'0')*10)+(isa_readb(0xffff6)-'0'); + month = ((isa_readb(0xffff8)-'0')*10)+(isa_readb(0xffff9)-'0'); + year = ((isa_readb(0xffffb)-'0')*10)+(isa_readb(0xffffc)-'0'); + tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6) + | ((day & 0x1f)<<1); +} + +/* /proc/toshiba read handler */ +static int +tosh_get_info(char* buffer, char** start, off_t fpos, int length) +{ + char* temp = buffer; + /* TODO: tosh_fn_status() */ + int key = 0; + + /* Format: + * 0) Linux driver version (this will change if format changes) + * 1) Machine ID + * 2) SCI version + * 3) BIOS version (major, minor) + * 4) BIOS date (in SCI date format) + * 5) Fn Key status + */ + + temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", + tosh_id, + (tosh_sci & 0xff00)>>8, + tosh_sci & 0xff, + (tosh_bios & 0xff00)>>8, + tosh_bios & 0xff, + tosh_date, + key); + + return temp-buffer; +} + +static int __init +old_driver_emulation_init(void) +{ + int status; + void __iomem *bios = ioremap(0xf0000, 0x10000); + if (!bios) + return -ENOMEM; + + if ((status = misc_register(&tosh_device))) { + printk(MY_ERR "failed to register misc device %d (\"%s\")\n", + tosh_device.minor, tosh_device.name); + return status; + } + + setup_tosh_info(bios); + create_proc_info_entry(OLD_PROC_TOSHIBA, 0, NULL, tosh_get_info); + + iounmap(bios); + + return 0; +} + +static void __exit +old_driver_emulation_exit(void) +{ + remove_proc_entry(OLD_PROC_TOSHIBA, NULL); + misc_deregister(&tosh_device); +} + +/* }}} end of /dev/toshiba and /proc/toshiba handlers */ + /* proc and module init */ @@ -538,16 +758,144 @@ .update_status = set_lcd_status, }; +static DECLARE_MUTEX_LOCKED(thread_sem); +static int thread_should_die; + +static struct acpi_device *threaded_device = 0; + +static void thread_deliver_button_event(u32 value) +{ + if (!threaded_device) return; + if( value == 0x0100 ) { + /* Ignore FN on its own */ + } else if( value & 0x80 ) { + acpi_bus_generate_event( threaded_device, 1, value & ~0x80 ); + } else { + acpi_bus_generate_event( threaded_device, 0, value ); + } +} + +static int toshiba_acpi_thread(void *data) +{ + int dropped = 0; + u32 hci_result, value; + + daemonize("ktoshkeyd"); + set_user_nice(current, 4); + thread_should_die = 0; + + up(&thread_sem); + + do { + /* In case we get stuck; we can rmmod the module here */ + if (thread_should_die) + break; + + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + dropped++; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result != HCI_EMPTY); + + printk(MY_INFO "Dropped %d keys from the queue on startup\n", dropped); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / hotkeys_check_per_sec); + + if (thread_should_die) + break; + + if (try_to_freeze()) + continue; + + do { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + thread_deliver_button_event(value); + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result == HCI_SUCCESS); + } + set_user_nice(current, -20); /* Become nasty so we are cleaned up + * before the module exits making us oops */ + up(&thread_sem); + return 0; +} + +static int acpi_toshkeys_add (struct acpi_device *device) +{ + threaded_device = device; + strcpy(acpi_device_name(device), "Toshiba laptop hotkeys"); + strcpy(acpi_device_class(device), "hkey"); + return 0; +} + +static int acpi_toshkeys_remove (struct acpi_device *device, int type) +{ + if (threaded_device == device) + threaded_device = 0; + return 0; +} + +static struct acpi_driver acpi_threaded_toshkeys = { + .name = "Toshiba laptop hotkeys driver", + .class = "hkey", + .ids = "TOS6200,TOS6207,TOS6208", + .ops = { + .add = acpi_toshkeys_add, + .remove = acpi_toshkeys_remove, + }, +}; + +static int __init init_threaded_acpi(void) +{ + acpi_status result = AE_OK; + result = acpi_bus_register_driver(&acpi_threaded_toshkeys); + if( result < 0 ) + printk(MY_ERR "Registration of toshkeys acpi device failed\n"); + return result; +} + +static void kill_threaded_acpi(void) +{ + acpi_bus_unregister_driver(&acpi_threaded_toshkeys); +} + static void toshiba_acpi_exit(void) { if (toshiba_backlight_device) backlight_device_unregister(toshiba_backlight_device); + if (hotkeys_over_acpi) { + thread_should_die = 1; + down(&thread_sem); + kill_threaded_acpi(); + } + remove_device(); if (toshiba_proc_dir) remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + old_driver_emulation_exit(); + return; } @@ -555,6 +903,7 @@ { acpi_status status = AE_OK; u32 hci_result; + int status2; if (acpi_disabled) return -ENODEV; @@ -571,6 +920,9 @@ TOSHIBA_ACPI_VERSION); printk(MY_INFO " HCI method: %s\n", method_hci); + if ((status2 = old_driver_emulation_init())) + return status2; + force_fan = 0; key_event_valid = 0; @@ -597,6 +949,25 @@ } toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + if (hotkeys_over_acpi && ACPI_SUCCESS(status)) { + printk(MY_INFO "Toshiba hotkeys are sent as ACPI events\n"); + if (hotkeys_check_per_sec < 1) + hotkeys_check_per_sec = 1; + if (hotkeys_check_per_sec > 10) + hotkeys_check_per_sec = 10; + printk(MY_INFO "ktoshkeyd will check %d time%s per second\n", + hotkeys_check_per_sec, hotkeys_check_per_sec==1?"":"s"); + if (init_threaded_acpi() >= 0) { + kernel_thread(toshiba_acpi_thread, NULL, CLONE_KERNEL); + down(&thread_sem); + } else { + remove_device(); + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + status = AE_ERROR; + printk(MY_INFO "ktoshkeyd initialisation failed. Refusing to load module\n"); + } + } + return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; } --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/video.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/video.c @@ -70,6 +70,10 @@ MODULE_DESCRIPTION("ACPI Video Driver"); MODULE_LICENSE("GPL"); +static int no_automatic_changes = 1; + +module_param(no_automatic_changes, uint, 0600); + static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); @@ -381,7 +385,6 @@ arg0.integer.value = level; status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); - printk(KERN_DEBUG "set_level status: %x\n", status); return status; } @@ -1715,8 +1718,6 @@ struct acpi_video_bus *video = data; struct acpi_device *device = NULL; - printk("video bus notify\n"); - if (!video) return; @@ -1772,7 +1773,8 @@ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ - acpi_video_switch_brightness(video_device, event); + if (!no_automatic_changes) + acpi_video_switch_brightness(video_device, event); acpi_bus_generate_event(device, event, 0); break; default: @@ -1783,6 +1785,7 @@ return; } +static int instance; static int acpi_video_bus_add(struct acpi_device *device) { int result = 0; @@ -1797,6 +1800,13 @@ if (!video) return -ENOMEM; + /* a hack to fix the duplicate name "VID" problem on T61 */ + if (!strcmp(device->pnp.bus_id, "VID")) { + if (instance) + device->pnp.bus_id[3] = '0' + instance; + instance ++; + } + video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/button.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/button.c @@ -68,6 +68,7 @@ static int acpi_button_add(struct acpi_device *device); static int acpi_button_remove(struct acpi_device *device, int type); +static int acpi_button_resume(struct acpi_device *device); static int acpi_button_info_open_fs(struct inode *inode, struct file *file); static int acpi_button_state_open_fs(struct inode *inode, struct file *file); @@ -77,6 +78,7 @@ .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E", .ops = { .add = acpi_button_add, + .resume = acpi_button_resume, .remove = acpi_button_remove, }, }; @@ -487,6 +489,29 @@ return 0; } +/* this is needed to learn about changes made in suspended state */ +static int acpi_button_resume(struct acpi_device *device) +{ + struct acpi_button *button; + struct acpi_handle *handle; + struct input_dev *input; + unsigned long state; + + button = device->driver_data; + handle = button->device->handle; + input = button->input; + + /* + * On resume we send the state; if it matches to what input layer + * thinks then the event will not even reach userspace. + */ + if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID", + NULL, &state))) + input_report_switch(input, SW_LID, !state); + + return 0; +} + static int __init acpi_button_init(void) { int result; --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/parser/psparse.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/parser/psparse.c @@ -56,6 +56,7 @@ #include #include #include +#include #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psparse") @@ -452,6 +453,7 @@ struct acpi_thread_state *thread; struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list; struct acpi_walk_state *previous_walk_state; + struct acpi_namespace_node *method_node; ACPI_FUNCTION_TRACE(ps_parse_aml); @@ -495,6 +497,18 @@ status = AE_OK; while (walk_state) { + method_node = walk_state->method_call_node; + + if (method_node && ((acpi_ns_get_attached_object(method_node))->method.method_flags & AML_METHOD_NOTIFY)) { + /* This is suboptimal */ + struct acpi_device *device = kzalloc(sizeof(struct acpi_device), GFP_ATOMIC); + strcpy (device->pnp.device_class, "METHOD"); + strcpy (device->pnp.bus_id, method_node->name.ascii); + acpi_bus_generate_event (device, 0, 0); + + kfree(device); + } + if (ACPI_SUCCESS(status)) { /* * The parse_loop executes AML until the method terminates --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/acpi/Kconfig @@ -261,6 +261,23 @@ Enter the full path name to the file which includes the AmlCode declaration. +config ACPI_CUSTOM_DSDT_INITRD + bool "Read Custom DSDT from initramfs" + depends on BLK_DEV_INITRD + default y + help + The DSDT (Differentiated System Description Table) often needs to be + overridden because of broken BIOS implementations. If this feature is + activated you will be able to provide a customized DSDT by adding it + to your initramfs. For now you need to use a special mkinitrd tool. + For more details see or + . If there is no table found, it + will fallback to the custom DSDT in-kernel (if activated) or to the + DSDT from the BIOS. + + Even if you do not need a new one at the moment, you may want to use a + better implemented DSDT later. It is safe to say Y here. + config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 default 0 --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/dock.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/dock.c @@ -716,6 +716,7 @@ if (ret) { printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); kfree(dock_station); + dock_station = NULL; return ret; } ret = device_create_file(&dock_device.dev, &dev_attr_docked); @@ -723,6 +724,7 @@ printk("Error %d adding sysfs file\n", ret); platform_device_unregister(&dock_device); kfree(dock_station); + dock_station = NULL; return ret; } ret = device_create_file(&dock_device.dev, &dev_attr_undock); @@ -731,6 +733,7 @@ device_remove_file(&dock_device.dev, &dev_attr_docked); platform_device_unregister(&dock_device); kfree(dock_station); + dock_station = NULL; return ret; } ret = device_create_file(&dock_device.dev, &dev_attr_uid); @@ -738,6 +741,7 @@ printk("Error %d adding sysfs file\n", ret); platform_device_unregister(&dock_device); kfree(dock_station); + dock_station = NULL; return ret; } @@ -750,6 +754,7 @@ dd = alloc_dock_dependent_device(handle); if (!dd) { kfree(dock_station); + dock_station = NULL; ret = -ENOMEM; goto dock_add_err_unregister; } @@ -777,6 +782,7 @@ device_remove_file(&dock_device.dev, &dev_attr_undock); platform_device_unregister(&dock_device); kfree(dock_station); + dock_station = NULL; return ret; } @@ -810,6 +816,7 @@ /* free dock station memory */ kfree(dock_station); + dock_station = NULL; return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/tables/tbfadt.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/tables/tbfadt.c @@ -211,14 +211,17 @@ * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. * Performs validation on some important FADT fields. * + * NOTE: We create a local copy of the FADT regardless of the version. + * ******************************************************************************/ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* - * Check if the FADT is larger than what we know about (ACPI 2.0 version). - * Truncate the table, but make some noise. + * Check if the FADT is larger than the largest table that we expect + * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue + * a warning. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, @@ -227,10 +230,12 @@ sizeof(struct acpi_table_fadt))); } - /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ + /* Clear the entire local FADT */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); + /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ + ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); @@ -251,7 +256,7 @@ * RETURN: None * * DESCRIPTION: Converts all versions of the FADT to a common internal format. - * -> Expand all 32-bit addresses to 64-bit. + * Expand all 32-bit addresses to 64-bit. * * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), * and must contain a copy of the actual FADT. @@ -292,8 +297,23 @@ } /* - * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address - * structures as necessary. + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which + * should be zero are indeed zero. This will workaround BIOSs that + * inadvertently place values in these fields. + * + * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at + * offset 45, 55, 95, and the word located at offset 109, 110. + */ + if (acpi_gbl_FADT.header.revision < 3) { + acpi_gbl_FADT.preferred_profile = 0; + acpi_gbl_FADT.pstate_control = 0; + acpi_gbl_FADT.cst_control = 0; + acpi_gbl_FADT.boot_flags = 0; + } + + /* + * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" + * generic address structures as necessary. */ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { target = @@ -349,18 +369,6 @@ acpi_gbl_FADT.xpm1a_event_block.space_id; } - - /* - * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero) - * are indeed zero. This will workaround BIOSs that inadvertently placed - * values in these fields. - */ - if (acpi_gbl_FADT.header.revision < 3) { - acpi_gbl_FADT.preferred_profile = 0; - acpi_gbl_FADT.pstate_control = 0; - acpi_gbl_FADT.cst_control = 0; - acpi_gbl_FADT.boot_flags = 0; - } } /****************************************************************************** --- linux-source-2.6.22-2.6.22.orig/drivers/acpi/tables/tbutils.c +++ linux-source-2.6.22-2.6.22/drivers/acpi/tables/tbutils.c @@ -51,6 +51,65 @@ static acpi_physical_address acpi_tb_get_root_table_entry(u8 * table_entry, acpi_native_uint table_entry_size); +/******************************************************************************* + * + * FUNCTION: acpi_tb_check_xsdt + * + * PARAMETERS: address - Pointer to the XSDT + * + * RETURN: status + * AE_OK - XSDT is okay + * AE_NO_MEMORY - can't map XSDT + * AE_INVALID_TABLE_LENGTH - invalid table length + * AE_NULL_ENTRY - XSDT has NULL entry + * + * DESCRIPTION: validate XSDT +******************************************************************************/ + +static acpi_status +acpi_tb_check_xsdt(acpi_physical_address address) +{ + struct acpi_table_header *table; + u32 length; + u64 xsdt_entry_address; + u8 *table_entry; + u32 table_count; + int i; + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) + return AE_NO_MEMORY; + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + if (length < sizeof(struct acpi_table_header)) + return AE_INVALID_TABLE_LENGTH; + + table = acpi_os_map_memory(address, length); + if (!table) + return AE_NO_MEMORY; + + /* Calculate the number of tables described in XSDT */ + table_count = + (u32) ((table->length - + sizeof(struct acpi_table_header)) / sizeof(u64)); + table_entry = + ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); + for (i = 0; i < table_count; i++) { + ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry); + if (!xsdt_entry_address) { + /* XSDT has NULL entry */ + break; + } + table_entry += sizeof(u64); + } + acpi_os_unmap_memory(table, length); + + if (i < table_count) + return AE_NULL_ENTRY; + else + return AE_OK; +} /******************************************************************************* * @@ -341,6 +400,7 @@ u32 table_count; struct acpi_table_header *table; acpi_physical_address address; + acpi_physical_address rsdt_address; u32 length; u8 *table_entry; acpi_status status; @@ -369,6 +429,8 @@ */ address = (acpi_physical_address) rsdp->xsdt_physical_address; table_entry_size = sizeof(u64); + rsdt_address = (acpi_physical_address) + rsdp->rsdt_physical_address; } else { /* Root table is an RSDT (32-bit physical addresses) */ @@ -382,6 +444,15 @@ */ acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); + if (table_entry_size == sizeof(u64)) { + if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { + /* XSDT has NULL entry, RSDT is used */ + address = rsdt_address; + table_entry_size = sizeof(u32); + ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry," + "using RSDT")); + } + } /* Map the RSDT/XSDT table header to get the full table length */ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); --- linux-source-2.6.22-2.6.22.orig/drivers/i2c/busses/Makefile +++ linux-source-2.6.22-2.6.22/drivers/i2c/busses/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o +obj-$(CONFIG_I2C_POULSBO) += i2c-sch.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.o obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o --- linux-source-2.6.22-2.6.22.orig/drivers/i2c/busses/i2c-sch.c +++ linux-source-2.6.22-2.6.22/drivers/i2c/busses/i2c-sch.c @@ -0,0 +1,396 @@ +/* + * i2c-sch.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * + * Based on piix4.c + * Copyright (c) 1998 - 2002 Frodo Looijaard and + * Philip Edelbrock + * + * 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. + */ + +/* + * Supports: + * Intel POULSBO + * + * Note: we assume there can only be one device, with one SMBus interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct sd { + const unsigned short mfr; + const unsigned short dev; + const unsigned char fn; + const char *name; +}; + +/* POULSBO SMBus address offsets */ +#define SMBHSTCNT (0 + poulsbo_smba) +#define SMBHSTSTS (1 + poulsbo_smba) +#define SMBHSTADD (4 + poulsbo_smba) /* TSA */ +#define SMBHSTCMD (5 + poulsbo_smba) +#define SMBHSTDAT0 (6 + poulsbo_smba) +#define SMBHSTDAT1 (7 + poulsbo_smba) +#define SMBBLKDAT (0x20 + poulsbo_smba) + +/* count for request_region */ +#define SMBIOSIZE 8 + +/* PCI Address Constants */ +#define SMBBA_SCH 0x040 + +/* Other settings */ +#define MAX_TIMEOUT 500 +#define ENABLE_INT9 0 + +/* POULSBO constants */ +#define POULSBO_QUICK 0x00 +#define POULSBO_BYTE 0x01 +#define POULSBO_BYTE_DATA 0x02 +#define POULSBO_WORD_DATA 0x03 +#define POULSBO_BLOCK_DATA 0x05 + +/* insmod parameters */ + +/* If force is set to anything different from 0, we forcibly enable the + POULSBO. DANGEROUS! */ +static int force; +module_param(force, int, 0); +MODULE_PARM_DESC(force, "Forcibly enable the POULSBO. DANGEROUS!"); + +static int poulsbo_transaction(void); + +static unsigned short poulsbo_smba; +static struct pci_driver poulsbo_driver; +static struct i2c_adapter poulsbo_adapter; + +static int __devinit poulsbo_setup(struct pci_dev *POULSBO_dev, + const struct pci_device_id *id) +{ + unsigned short smbase; + if (POULSBO_dev->device != PCI_DEVICE_ID_INTEL_POULSBO_LPC) { + /* match up the function */ + if (PCI_FUNC(POULSBO_dev->devfn) != id->driver_data) + return -ENODEV; + dev_info(&POULSBO_dev->dev, "Found %s device\n", + pci_name(POULSBO_dev)); + } else { + dev_info(&POULSBO_dev->dev, "Found POULSBO SMBUS %s device\n", + pci_name(POULSBO_dev)); + /* find SMBUS base address */ + pci_read_config_word(POULSBO_dev, 0x40, &smbase); + dev_info(&POULSBO_dev->dev, "POULSBO SM base = 0x%04x\n", + smbase); + } + + /* Determine the address of the SMBus areas */ + if (POULSBO_dev->device == PCI_DEVICE_ID_INTEL_POULSBO_LPC) + pci_read_config_word(POULSBO_dev, SMBBA_SCH, &poulsbo_smba); + else + poulsbo_smba = 0; + + poulsbo_smba &= 0xfff0; + if (poulsbo_smba == 0) { + dev_err(&POULSBO_dev->dev, "SMB base address " + "uninitialized - upgrade BIOS or use " + "force_addr=0xaddr\n"); + return -ENODEV; + } + + if (!request_region(poulsbo_smba, SMBIOSIZE, poulsbo_driver.name)) { + dev_err(&POULSBO_dev->dev, "SMB region 0x%x already in use!\n", + poulsbo_smba); + return -ENODEV; + } + + dev_dbg(&POULSBO_dev->dev, "SMBA = 0x%X\n", poulsbo_smba); + + return 0; +} + +/* Another internally used function */ +static int poulsbo_transaction(void) +{ + int temp; + int result = 0; + int timeout = 0; + + dev_dbg(&poulsbo_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), + inb_p(SMBHSTDAT1)); + + /* Make sure the SMBus host is ready to start transmitting */ + temp = inb_p(SMBHSTSTS); + if (temp != 0x00) { + if (temp == 1) { + dev_dbg(&poulsbo_adapter.dev, "Completion (%02x). " + "clear...\n", temp); + outb_p(temp, SMBHSTSTS); + + } else if (temp & 0xe) { + dev_dbg(&poulsbo_adapter.dev, "SMBus error (%02x). " + "Resetting...\n", temp); + outb_p(temp, SMBHSTSTS); + } + temp = inb_p(SMBHSTSTS); + if (temp != 0x00) { + dev_err(&poulsbo_adapter.dev, "Failed! (%02x)\n", temp); + return -1; + } else { + dev_dbg(&poulsbo_adapter.dev, "Successfull!\n"); + } + } + + /* start the transaction by setting bit 4 */ + outb_p(inb(SMBHSTCNT) | 0x10, SMBHSTCNT); + + /* Errata: We will always wait for a fraction of a second! */ + do { + msleep(1); + temp = inb_p(SMBHSTSTS); + } while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT)); + + /* If the SMBus is still busy, we give up */ + if (timeout >= MAX_TIMEOUT) { + dev_err(&poulsbo_adapter.dev, "SMBus Timeout!\n"); + result = -1; + } + + if (temp & 0x10) { + result = -1; + dev_err(&poulsbo_adapter.dev, + "Error: Failed bus transaction\n"); + } + + if (temp & 0x08) { + result = -1; + dev_dbg(&poulsbo_adapter.dev, "Bus collision! SMBus may be " + "locked until next hard reset. (sorry!)\n"); + /* Clock stops and slave is stuck in mid-transmission */ + } + + if (temp & 0x04) { + result = -1; + dev_dbg(&poulsbo_adapter.dev, "Error: no response!\n"); + } + + temp = inb_p(SMBHSTSTS); + if (temp != 0x00) { + if (temp == 0x1) { + dev_dbg(&poulsbo_adapter.dev, "post complete!\n"); + outb_p(temp, SMBHSTSTS); + } else if (temp & 0xe) { + dev_dbg(&poulsbo_adapter.dev, "Error: bus, etc!\n"); + outb_p(inb(SMBHSTSTS), SMBHSTSTS); + } + } + msleep(1); + + temp = inb_p(SMBHSTSTS); + if (temp & 0xe) { + /* BSY, device or bus error */ + dev_err(&poulsbo_adapter.dev, "Failed reset at end of " + "transaction (%02x), Bus error\n", temp); + } + dev_dbg(&poulsbo_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), + inb_p(SMBHSTDAT1)); + return result; +} + +/* Return -1 on error. */ +static s32 poulsbo_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + int i, len; + dev_dbg(&poulsbo_adapter.dev, "access size: %d %s\n", size, + (read_write) ? "READ" : "WRITE"); + switch (size) { + case I2C_SMBUS_PROC_CALL: + dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); + return -1; + case I2C_SMBUS_QUICK: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); + size = POULSBO_QUICK; + break; + case I2C_SMBUS_BYTE: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); + if (read_write == I2C_SMBUS_WRITE) + outb_p(command, SMBHSTCMD); + size = POULSBO_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) + outb_p(data->byte, SMBHSTDAT0); + size = POULSBO_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + outb_p(data->word & 0xff, SMBHSTDAT0); + outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); + } + size = POULSBO_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + len = data->block[0]; + if (len < 0) + len = 0; + if (len > 32) + len = 32; + outb_p(len, SMBHSTDAT0); + i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + for (i = 1; i <= len; i++) + outb_p(data->block[i], SMBBLKDAT); + } + size = POULSBO_BLOCK_DATA; + break; + } + dev_dbg(&poulsbo_adapter.dev, "write size %d to 0x%04x\n", size, + SMBHSTCNT); + outb_p((size & 0x7), SMBHSTCNT); + + if (poulsbo_transaction()) /* Error in transaction */ + return -1; + + if ((read_write == I2C_SMBUS_WRITE) || (size == POULSBO_QUICK)) + return 0; + + switch (size) { + case POULSBO_BYTE: + /* FIXME: Where is the result put? I assume here it is in + * SMBHSTDAT0 but it might just as well be in the SMBHSTCMD. + * No clue in the docs */ + data->byte = inb_p(SMBHSTDAT0); + break; + case POULSBO_BYTE_DATA: + data->byte = inb_p(SMBHSTDAT0); + break; + case POULSBO_WORD_DATA: + data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); + break; + case POULSBO_BLOCK_DATA: + data->block[0] = inb_p(SMBHSTDAT0); + i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ + for (i = 1; i <= data->block[0]; i++) + data->block[i] = inb_p(SMBBLKDAT); + break; + } + return 0; +} + +static u32 poulsbo_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm smbus_algorithm = { + .smbus_xfer = poulsbo_access, + .functionality = poulsbo_func, +}; + +static struct i2c_adapter poulsbo_adapter = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo = &smbus_algorithm, +}; + +static struct pci_device_id poulsbo_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_POULSBO_LPC), + .driver_data = 0xf8}, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, poulsbo_ids); + +static int __devinit poulsbo_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + int retval; + retval = poulsbo_setup(dev, id); + if (retval) + return retval; + + /* set up the driverfs linkage to our parent device */ + poulsbo_adapter.dev.parent = &dev->dev; + + snprintf(poulsbo_adapter.name, I2C_NAME_SIZE, + "SMBus POULSBO adapter at %04x", poulsbo_smba); + + retval = i2c_add_adapter(&poulsbo_adapter); + if (retval) { + dev_err(&dev->dev, "Couldn't register adapter!\n"); + release_region(poulsbo_smba, SMBIOSIZE); + poulsbo_smba = 0; + } + + return retval; +} + +static void __devexit poulsbo_remove(struct pci_dev *dev) +{ + if (poulsbo_smba) { + i2c_del_adapter(&poulsbo_adapter); + release_region(poulsbo_smba, SMBIOSIZE); + poulsbo_smba = 0; + } +} + +static struct pci_driver poulsbo_driver = { + .name = "poulsbo_smbus", + .id_table = poulsbo_ids, + .probe = poulsbo_probe, + .remove = __devexit_p(poulsbo_remove), +}; + +static int __init i2c_poulsbo_init(void) +{ + return pci_register_driver(&poulsbo_driver); +} + +static void __exit i2c_poulsbo_exit(void) +{ + pci_unregister_driver(&poulsbo_driver); +} + +MODULE_AUTHOR("Jacob Pan "); +MODULE_DESCRIPTION("POULSBO SMBus driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_poulsbo_init); +module_exit(i2c_poulsbo_exit); --- linux-source-2.6.22-2.6.22.orig/drivers/i2c/busses/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/i2c/busses/Kconfig @@ -216,6 +216,18 @@ This driver can also be built as a module. If so, the module will be called i2c-piix4. +config I2C_POULSBO + tristate "Intel SCH (Poulsbo SMBUS 1.0)" + depends on I2C && PCI + help + If you say yes to this option, support will be included for the Intel + SCH (POULSBO) + + This driver can also be built as a module. If so, the module + will be called i2c-sch. + + + config I2C_IBM_IIC tristate "IBM PPC 4xx on-chip I2C interface" depends on IBM_OCP --- linux-source-2.6.22-2.6.22.orig/drivers/serial/sunzilog.c +++ linux-source-2.6.22-2.6.22/drivers/serial/sunzilog.c @@ -9,7 +9,7 @@ * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their * work there. * - * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 2002, 2006, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -1151,11 +1151,22 @@ { struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; unsigned long flags; + int locked = 1; + + local_irq_save(flags); + if (up->port.sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&up->port.lock); + } else + spin_lock(&up->port.lock); - spin_lock_irqsave(&up->port.lock, flags); uart_console_write(&up->port, s, count, sunzilog_putchar); udelay(2); - spin_unlock_irqrestore(&up->port.lock, flags); + + if (locked) + spin_unlock(&up->port.lock); + local_irq_restore(flags); } static int __init sunzilog_console_setup(struct console *con, char *options) @@ -1215,23 +1226,6 @@ static inline struct console *SUNZILOG_CONSOLE(void) { - int i; - - if (con_is_present()) - return NULL; - - for (i = 0; i < NUM_CHANNELS; i++) { - int this_minor = sunzilog_reg.minor + i; - - if ((this_minor - 64) == (serial_console - 1)) - break; - } - if (i == NUM_CHANNELS) - return NULL; - - sunzilog_console_ops.index = i; - sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; - return &sunzilog_console_ops; } @@ -1417,12 +1411,18 @@ sunzilog_init_hw(&up[1]); if (!keyboard_mouse) { + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + &sunzilog_reg, up[0].port.line)) + up->flags |= SUNZILOG_FLAG_IS_CONS; err = uart_add_one_port(&sunzilog_reg, &up[0].port); if (err) { of_iounmap(&op->resource[0], rp, sizeof(struct zilog_layout)); return err; } + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + &sunzilog_reg, up[1].port.line)) + up->flags |= SUNZILOG_FLAG_IS_CONS; err = uart_add_one_port(&sunzilog_reg, &up[1].port); if (err) { uart_remove_one_port(&sunzilog_reg, &up[0].port); @@ -1520,7 +1520,6 @@ goto out_free_tables; sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; - sunzilog_reg.cons = SUNZILOG_CONSOLE(); sunserial_current_minor += uart_count; } --- linux-source-2.6.22-2.6.22.orig/drivers/serial/sunhv.c +++ linux-source-2.6.22-2.6.22/drivers/serial/sunhv.c @@ -258,17 +258,7 @@ /* port->lock held by caller. */ static void sunhv_start_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->info->xmit; - - while (!uart_circ_empty(xmit)) { - long status = sun4v_con_putchar(xmit->buf[xmit->tail]); - - if (status != HV_EOK) - break; - - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } + transmit_chars(port); } /* port->lock is not held. */ @@ -440,8 +430,16 @@ { struct uart_port *port = sunhv_port; unsigned long flags; + int locked = 1; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else + spin_lock(&port->lock); - spin_lock_irqsave(&port->lock, flags); while (n > 0) { unsigned long ra = __pa(con_write_page); unsigned long page_bytes; @@ -469,7 +467,10 @@ ra += written; } } - spin_unlock_irqrestore(&port->lock, flags); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); } static inline void sunhv_console_putchar(struct uart_port *port, char c) @@ -488,7 +489,15 @@ { struct uart_port *port = sunhv_port; unsigned long flags; - int i; + int i, locked = 1; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else + spin_lock(&port->lock); spin_lock_irqsave(&port->lock, flags); for (i = 0; i < n; i++) { @@ -496,7 +505,10 @@ sunhv_console_putchar(port, '\r'); sunhv_console_putchar(port, *s++); } - spin_unlock_irqrestore(&port->lock, flags); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); } static struct console sunhv_console = { @@ -508,16 +520,6 @@ .data = &sunhv_reg, }; -static inline struct console *SUNHV_CONSOLE(void) -{ - if (con_is_present()) - return NULL; - - sunhv_console.index = 0; - - return &sunhv_console; -} - static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match) { struct uart_port *port; @@ -570,7 +572,8 @@ sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; sunserial_current_minor += 1; - sunhv_reg.cons = SUNHV_CONSOLE(); + sunserial_console_match(&sunhv_console, op->node, + &sunhv_reg, port->line); err = uart_add_one_port(&sunhv_reg, port); if (err) --- linux-source-2.6.22-2.6.22.orig/drivers/serial/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/serial/Kconfig @@ -74,21 +74,17 @@ depends on SERIAL_8250 && PCI default SERIAL_8250 help - Say Y here if you have PCI serial ports. - - To compile this driver as a module, choose M here: the module - will be called 8250_pci. + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. config SERIAL_8250_PNP tristate "8250/16550 PNP device support" if EMBEDDED depends on SERIAL_8250 && PNP default SERIAL_8250 help - Say Y here if you have serial ports described by PNPBIOS or ACPI. - These are typically ports built into the system board. - - To compile this driver as a module, choose M here: the module - will be called 8250_pnp. + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. config SERIAL_8250_HP300 tristate --- linux-source-2.6.22-2.6.22.orig/drivers/serial/sunsab.c +++ linux-source-2.6.22-2.6.22/drivers/serial/sunsab.c @@ -38,7 +38,7 @@ #include #include -#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ #endif @@ -58,6 +58,7 @@ unsigned char interrupt_mask1;/* ISR1 masking */ unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ + unsigned int gis_shift; int type; /* SAB82532 version */ /* Setting configuration bits while the transmitter is active @@ -305,13 +306,15 @@ struct tty_struct *tty; union sab82532_irq_status status; unsigned long flags; + unsigned char gis; spin_lock_irqsave(&up->port.lock, flags); status.stat = 0; - if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA0) + gis = readb(&up->regs->r.gis) >> up->gis_shift; + if (gis & 1) status.sreg.isr0 = readb(&up->regs->r.isr0); - if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1) + if (gis & 2) status.sreg.isr1 = readb(&up->regs->r.isr1); tty = NULL; @@ -327,35 +330,6 @@ transmit_chars(up, &status); } - spin_unlock(&up->port.lock); - - if (tty) - tty_flip_buffer_push(tty); - - up++; - - spin_lock(&up->port.lock); - - status.stat = 0; - if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB0) - status.sreg.isr0 = readb(&up->regs->r.isr0); - if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1) - status.sreg.isr1 = readb(&up->regs->r.isr1); - - tty = NULL; - if (status.stat) { - if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | - SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || - (status.sreg.isr1 & SAB82532_ISR1_BRK)) - - tty = receive_chars(up, &status); - if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || - (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC))) - check_status(up, &status); - if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR)) - transmit_chars(up, &status); - } - spin_unlock_irqrestore(&up->port.lock, flags); if (tty) @@ -539,6 +513,10 @@ struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; unsigned long flags; unsigned char tmp; + int err = request_irq(up->port.irq, sunsab_interrupt, + IRQF_SHARED, "sab", up); + if (err) + return err; spin_lock_irqsave(&up->port.lock, flags); @@ -641,6 +619,7 @@ #endif spin_unlock_irqrestore(&up->port.lock, flags); + free_irq(up->port.irq, up); } /* @@ -860,22 +839,31 @@ static void sunsab_console_putchar(struct uart_port *port, int c) { struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); sunsab_tec_wait(up); writeb(c, &up->regs->w.tic); - - spin_unlock_irqrestore(&up->port.lock, flags); } static void sunsab_console_write(struct console *con, const char *s, unsigned n) { struct uart_sunsab_port *up = &sunsab_ports[con->index]; + unsigned long flags; + int locked = 1; + + local_irq_save(flags); + if (up->port.sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&up->port.lock); + } else + spin_lock(&up->port.lock); uart_console_write(&up->port, s, n, sunsab_console_putchar); sunsab_tec_wait(up); + + if (locked) + spin_unlock(&up->port.lock); + local_irq_restore(flags); } static int sunsab_console_setup(struct console *con, char *options) @@ -959,22 +947,6 @@ static inline struct console *SUNSAB_CONSOLE(void) { - int i; - - if (con_is_present()) - return NULL; - - for (i = 0; i < num_channels; i++) { - int this_minor = sunsab_reg.minor + i; - - if ((this_minor - 64) == (serial_console - 1)) - break; - } - if (i == num_channels) - return NULL; - - sunsab_console.index = i; - return &sunsab_console; } #else @@ -1015,9 +987,11 @@ if ((up->port.line & 0x1) == 0) { up->pvr_dsr_bit = (1 << 0); up->pvr_dtr_bit = (1 << 1); + up->gis_shift = 2; } else { up->pvr_dsr_bit = (1 << 3); up->pvr_dtr_bit = (1 << 2); + up->gis_shift = 0; } up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4); writeb(up->cached_pvr, &up->regs->w.pvr); @@ -1030,19 +1004,6 @@ up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; - if (!(up->port.line & 0x01)) { - int err; - - err = request_irq(up->port.irq, sunsab_interrupt, - IRQF_SHARED, "sab", up); - if (err) { - of_iounmap(&op->resource[0], - up->port.membase, - sizeof(union sab82532_async_regs)); - return err; - } - } - return 0; } @@ -1058,47 +1019,60 @@ 0, (inst * 2) + 0); if (err) - return err; + goto out; err = sunsab_init_one(&up[1], op, sizeof(union sab82532_async_regs), (inst * 2) + 1); - if (err) { - of_iounmap(&op->resource[0], - up[0].port.membase, - sizeof(union sab82532_async_regs)); - free_irq(up[0].port.irq, &up[0]); - return err; - } + if (err) + goto out1; - uart_add_one_port(&sunsab_reg, &up[0].port); - uart_add_one_port(&sunsab_reg, &up[1].port); + sunserial_console_match(SUNSAB_CONSOLE(), op->node, + &sunsab_reg, up[0].port.line); + + sunserial_console_match(SUNSAB_CONSOLE(), op->node, + &sunsab_reg, up[1].port.line); + + err = uart_add_one_port(&sunsab_reg, &up[0].port); + if (err) + goto out2; + + err = uart_add_one_port(&sunsab_reg, &up[1].port); + if (err) + goto out3; dev_set_drvdata(&op->dev, &up[0]); inst++; return 0; -} - -static void __devexit sab_remove_one(struct uart_sunsab_port *up) -{ - struct of_device *op = to_of_device(up->port.dev); - uart_remove_one_port(&sunsab_reg, &up->port); - if (!(up->port.line & 1)) - free_irq(up->port.irq, up); +out3: + uart_remove_one_port(&sunsab_reg, &up[0].port); +out2: of_iounmap(&op->resource[0], - up->port.membase, + up[1].port.membase, sizeof(union sab82532_async_regs)); +out1: + of_iounmap(&op->resource[0], + up[0].port.membase, + sizeof(union sab82532_async_regs)); +out: + return err; } static int __devexit sab_remove(struct of_device *op) { struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); - sab_remove_one(&up[0]); - sab_remove_one(&up[1]); + uart_remove_one_port(&sunsab_reg, &up[1].port); + uart_remove_one_port(&sunsab_reg, &up[0].port); + of_iounmap(&op->resource[0], + up[1].port.membase, + sizeof(union sab82532_async_regs)); + of_iounmap(&op->resource[0], + up[0].port.membase, + sizeof(union sab82532_async_regs)); dev_set_drvdata(&op->dev, NULL); @@ -1145,6 +1119,7 @@ sunsab_reg.minor = sunserial_current_minor; sunsab_reg.nr = num_channels; + sunsab_reg.cons = SUNSAB_CONSOLE(); err = uart_register_driver(&sunsab_reg); if (err) { @@ -1155,7 +1130,6 @@ } sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64; - sunsab_reg.cons = SUNSAB_CONSOLE(); sunserial_current_minor += num_channels; } --- linux-source-2.6.22-2.6.22.orig/drivers/serial/sunsu.c +++ linux-source-2.6.22-2.6.22/drivers/serial/sunsu.c @@ -1288,7 +1288,17 @@ unsigned int count) { struct uart_sunsu_port *up = &sunsu_ports[co->index]; + unsigned long flags; unsigned int ier; + int locked = 1; + + local_irq_save(flags); + if (up->port.sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&up->port.lock); + } else + spin_lock(&up->port.lock); /* * First save the UER then disable the interrupts @@ -1304,6 +1314,10 @@ */ wait_for_xmitr(up); serial_out(up, UART_IER, ier); + + if (locked) + spin_unlock(&up->port.lock); + local_irq_restore(flags); } /* @@ -1357,28 +1371,12 @@ * Register console. */ -static inline struct console *SUNSU_CONSOLE(int num_uart) +static inline struct console *SUNSU_CONSOLE(void) { - int i; - - if (con_is_present()) - return NULL; - - for (i = 0; i < num_uart; i++) { - int this_minor = sunsu_reg.minor + i; - - if ((this_minor - 64) == (serial_console - 1)) - break; - } - if (i == num_uart) - return NULL; - - sunsu_console.index = i; - return &sunsu_console; } #else -#define SUNSU_CONSOLE(num_uart) (NULL) +#define SUNSU_CONSOLE() (NULL) #define sunsu_serial_console_init() do { } while (0) #endif @@ -1468,6 +1466,8 @@ up->port.ops = &sunsu_pops; + sunserial_console_match(SUNSU_CONSOLE(), dp, + &sunsu_reg, up->port.line); err = uart_add_one_port(&sunsu_reg, &up->port); if (err) goto out_unmap; @@ -1558,7 +1558,6 @@ return err; sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64; sunserial_current_minor += num_uart; - sunsu_reg.cons = SUNSU_CONSOLE(num_uart); } err = of_register_driver(&su_driver, &of_bus_type); --- linux-source-2.6.22-2.6.22.orig/drivers/serial/8250_pnp.c +++ linux-source-2.6.22-2.6.22/drivers/serial/8250_pnp.c @@ -327,6 +327,7 @@ { "WACF004", 0 }, { "WACF005", 0 }, { "WACF006", 0 }, + { "WACF008", 0 }, /* Compaq touchscreen */ { "FPI2002", 0 }, /* Fujitsu Stylistic touchscreens */ --- linux-source-2.6.22-2.6.22.orig/drivers/serial/suncore.c +++ linux-source-2.6.22-2.6.22/drivers/serial/suncore.c @@ -16,9 +16,10 @@ #include #include #include +#include #include -#include +#include #include "suncore.h" @@ -26,92 +27,60 @@ EXPORT_SYMBOL(sunserial_current_minor); -void -sunserial_console_termios(struct console *con) +int sunserial_console_match(struct console *con, struct device_node *dp, + struct uart_driver *drv, int line) { - char mode[16], buf[16], *s; - char mode_prop[] = "ttyX-mode"; - char cd_prop[] = "ttyX-ignore-cd"; - char dtr_prop[] = "ttyX-rts-dtr-off"; - char *ssp_console_modes_prop = "ssp-console-modes"; - int baud, bits, stop, cflag; - char parity; - int carrier = 0; - int rtsdtr = 1; - int topnd, nd; - - if (!serial_console) - return; - - switch (serial_console) { - case PROMDEV_OTTYA: - mode_prop[3] = 'a'; - cd_prop[3] = 'a'; - dtr_prop[3] = 'a'; - break; - - case PROMDEV_OTTYB: - mode_prop[3] = 'b'; - cd_prop[3] = 'b'; - dtr_prop[3] = 'b'; - break; - - case PROMDEV_ORSC: - - nd = prom_pathtoinode("rsc"); - if (!nd) { - strcpy(mode, "115200,8,n,1,-"); - goto no_options; - } + int off; - if (!prom_node_has_property(nd, ssp_console_modes_prop)) { - strcpy(mode, "115200,8,n,1,-"); - goto no_options; - } + if (!con || of_console_device != dp) + return 0; - memset(mode, 0, sizeof(mode)); - prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode)); - goto no_options; + off = 0; + if (of_console_options && + *of_console_options == 'b') + off = 1; - default: - strcpy(mode, "9600,8,n,1,-"); - goto no_options; - } + if ((line & 1) != off) + return 0; - topnd = prom_getchild(prom_root_node); - nd = prom_searchsiblings(topnd, "options"); - if (!nd) { - strcpy(mode, "9600,8,n,1,-"); - goto no_options; - } - - if (!prom_node_has_property(nd, mode_prop)) { - strcpy(mode, "9600,8,n,1,-"); - goto no_options; - } + con->index = line; + drv->cons = con; + add_preferred_console(con->name, line, NULL); - memset(mode, 0, sizeof(mode)); - prom_getstring(nd, mode_prop, mode, sizeof(mode)); - - if (prom_node_has_property(nd, cd_prop)) { - memset(buf, 0, sizeof(buf)); - prom_getstring(nd, cd_prop, buf, sizeof(buf)); - if (!strcmp(buf, "false")) - carrier = 1; - - /* XXX: this is unused below. */ - } + return 1; +} +EXPORT_SYMBOL(sunserial_console_match); - if (prom_node_has_property(nd, dtr_prop)) { - memset(buf, 0, sizeof(buf)); - prom_getstring(nd, dtr_prop, buf, sizeof(buf)); - if (!strcmp(buf, "false")) - rtsdtr = 0; +void +sunserial_console_termios(struct console *con) +{ + struct device_node *dp; + const char *od, *mode, *s; + char mode_prop[] = "ttyX-mode"; + int baud, bits, stop, cflag; + char parity; - /* XXX: this is unused below. */ + dp = of_find_node_by_path("/options"); + od = of_get_property(dp, "output-device", NULL); + if (!strcmp(od, "rsc")) { + mode = of_get_property(of_console_device, + "ssp-console-modes", NULL); + if (!mode) + mode = "115200,8,n,1,-"; + } else { + char c; + + c = 'a'; + if (of_console_options) + c = *of_console_options; + + mode_prop[3] = c; + + mode = of_get_property(dp, mode_prop, NULL); + if (!mode) + mode = "9600,8,n,1,-"; } -no_options: cflag = CREAD | HUPCL | CLOCAL; s = mode; --- linux-source-2.6.22-2.6.22.orig/drivers/serial/suncore.h +++ linux-source-2.6.22-2.6.22/drivers/serial/suncore.h @@ -24,6 +24,8 @@ extern int sunserial_current_minor; +extern int sunserial_console_match(struct console *, struct device_node *, + struct uart_driver *, int); extern void sunserial_console_termios(struct console *); #endif /* !(_SERIAL_SUN_H) */ --- linux-source-2.6.22-2.6.22.orig/drivers/firewire/fw-ohci.c +++ linux-source-2.6.22-2.6.22/drivers/firewire/fw-ohci.c @@ -586,7 +586,7 @@ break; fw_notify("context_stop: still active (0x%08x)\n", reg); - msleep(1); + mdelay(1); } } @@ -1934,14 +1934,12 @@ free_irq(pdev->irq, ohci); err = pci_save_state(pdev); if (err) { - fw_error("pci_save_state failed with %d", err); + fw_error("pci_save_state failed with %d\n", err); return err; } err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); - if (err) { - fw_error("pci_set_power_state failed with %d", err); - return err; - } + if (err) + fw_error("pci_set_power_state failed with %d\n", err); return 0; } @@ -1955,7 +1953,7 @@ pci_restore_state(pdev); err = pci_enable_device(pdev); if (err) { - fw_error("pci_enable_device failed with %d", err); + fw_error("pci_enable_device failed with %d\n", err); return err; } --- linux-source-2.6.22-2.6.22.orig/drivers/firewire/fw-transaction.c +++ linux-source-2.6.22-2.6.22/drivers/firewire/fw-transaction.c @@ -605,8 +605,10 @@ * check is sufficient to ensure we don't send response to * broadcast packets or posted writes. */ - if (request->ack != ACK_PENDING) + if (request->ack != ACK_PENDING) { + kfree(request); return; + } if (rcode == RCODE_COMPLETE) fw_fill_response(&request->response, request->request_header, --- linux-source-2.6.22-2.6.22.orig/drivers/firewire/fw-transaction.h +++ linux-source-2.6.22-2.6.22/drivers/firewire/fw-transaction.h @@ -124,6 +124,10 @@ size_t length, void *callback_data); +/* + * Important note: The callback must guarantee that either fw_send_response() + * or kfree() is called on the @request. + */ typedef void (*fw_address_callback_t)(struct fw_card *card, struct fw_request *request, int tcode, int destination, int source, @@ -228,7 +232,7 @@ unsigned long reset_jiffies; unsigned long long guid; - int max_receive; + unsigned max_receive; int link_speed; int config_rom_generation; --- linux-source-2.6.22-2.6.22.orig/drivers/firewire/fw-sbp2.c +++ linux-source-2.6.22-2.6.22/drivers/firewire/fw-sbp2.c @@ -985,6 +985,7 @@ struct fw_unit *unit = sd->unit; struct fw_device *device = fw_device(unit->device.parent); struct sbp2_command_orb *orb; + unsigned max_payload; /* * Bidirectional commands are not yet implemented, and unknown @@ -1023,8 +1024,10 @@ * specifies the max payload size as 2 ^ (max_payload + 2), so * if we set this to max_speed + 7, we get the right value. */ + max_payload = device->node->max_speed + 7; + max_payload = min(max_payload, device->card->max_receive - 1); orb->request.misc = - COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | + COMMAND_ORB_MAX_PAYLOAD(max_payload) | COMMAND_ORB_SPEED(device->node->max_speed) | COMMAND_ORB_NOTIFY; --- linux-source-2.6.22-2.6.22.orig/drivers/ide/ide-cd.h +++ linux-source-2.6.22-2.6.22/drivers/ide/ide-cd.h @@ -15,7 +15,7 @@ memory, though. */ #ifndef VERBOSE_IDE_CD_ERRORS -#define VERBOSE_IDE_CD_ERRORS 1 +#define VERBOSE_IDE_CD_ERRORS 0 #endif --- linux-source-2.6.22-2.6.22.orig/drivers/ide/ide-disk.c +++ linux-source-2.6.22-2.6.22/drivers/ide/ide-disk.c @@ -481,6 +481,19 @@ && id->lba_capacity_2; } +#ifdef CONFIG_BLK_DEV_IDEDMA + /* REMOVE FOR HARDY */ +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { "ST320413A", NULL }, + { NULL, NULL } +}; +#endif + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +505,18 @@ else set_max = idedisk_read_native_max_address(drive); +#ifdef CONFIG_BLK_DEV_IDEDMA + /* REMOVE FOR HARDY */ + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } +#endif + if (set_max <= capacity) return; --- linux-source-2.6.22-2.6.22.orig/drivers/ide/pci/piix.c +++ linux-source-2.6.22-2.6.22/drivers/ide/pci/piix.c @@ -350,6 +350,7 @@ case PCI_DEVICE_ID_INTEL_ICH7_21: case PCI_DEVICE_ID_INTEL_ESB2_18: case PCI_DEVICE_ID_INTEL_ICH8_6: + case PCI_DEVICE_ID_INTEL_POULSBO_IDE: return 1; } @@ -512,8 +513,18 @@ /* 22 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */ /* 23 */ DECLARE_PIIX_DEV("ESB2", 0x3f), /* udma0-5 */ /* 24 */ DECLARE_PIIX_DEV("ICH8M", 0x3f), /* udma0-5 */ + /* 25 */ + { + .name = "POULSBO", + .init_chipset = init_chipset_piix, + .init_hwif = init_hwif_piix, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x83, 0x80, 0x80}, {0x87, 0x80, 0x80}}, + .bootable = ON_BOARD, + .udma_mask = 0x3f, + }, }; - /** * piix_init_one - called when a PIIX is found * @dev: the piix device @@ -589,6 +600,7 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 24}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_POULSBO_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 25}, { 0, }, }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); --- linux-source-2.6.22-2.6.22.orig/drivers/ide/ide-dma.c +++ linux-source-2.6.22-2.6.22/drivers/ide/ide-dma.c @@ -153,6 +153,8 @@ return 0; } +EXPORT_SYMBOL_GPL(ide_in_drive_list); + /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for --- linux-source-2.6.22-2.6.22.orig/drivers/hid/usbhid/hid-quirks.c +++ linux-source-2.6.22-2.6.22/drivers/hid/usbhid/hid-quirks.c @@ -63,6 +63,9 @@ #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_IR 0x8240 +#define USB_VENDOR_ID_ASUS 0x0b05 +#define USB_DEVICE_ID_ASUS_LCM 0x1726 + #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 #define USB_DEVICE_ID_ATEN_CS124U 0x2202 @@ -452,6 +455,8 @@ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, + { 0, 0 } }; --- linux-source-2.6.22-2.6.22.orig/drivers/Makefile +++ linux-source-2.6.22-2.6.22/drivers/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ +obj-$(CONFIG_MSS) += mmc/ obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ --- linux-source-2.6.22-2.6.22.orig/drivers/cpufreq/cpufreq_ondemand.c +++ linux-source-2.6.22-2.6.22/drivers/cpufreq/cpufreq_ondemand.c @@ -96,15 +96,25 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu) { - cputime64_t retval; + cputime64_t idle_time; + cputime64_t cur_jiffies; + cputime64_t busy_time; - retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, - kstat_cpu(cpu).cpustat.iowait); + cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); + busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user, + kstat_cpu(cpu).cpustat.system); - if (dbs_tuners_ins.ignore_nice) - retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal); - return retval; + if (!dbs_tuners_ins.ignore_nice) { + busy_time = cputime64_add(busy_time, + kstat_cpu(cpu).cpustat.nice); + } + + idle_time = cputime64_sub(cur_jiffies, busy_time); + return idle_time; } /* @@ -325,7 +335,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) { unsigned int idle_ticks, total_ticks; - unsigned int load; + unsigned int load = 0; cputime64_t cur_jiffies; struct cpufreq_policy *policy; @@ -339,7 +349,8 @@ cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); total_ticks = (unsigned int) cputime64_sub(cur_jiffies, this_dbs_info->prev_cpu_wall); - this_dbs_info->prev_cpu_wall = cur_jiffies; + this_dbs_info->prev_cpu_wall = get_jiffies_64(); + if (!total_ticks) return; /* @@ -370,7 +381,8 @@ if (tmp_idle_ticks < idle_ticks) idle_ticks = tmp_idle_ticks; } - load = (100 * (total_ticks - idle_ticks)) / total_ticks; + if (likely(total_ticks > idle_ticks)) + load = (100 * (total_ticks - idle_ticks)) / total_ticks; /* Check for frequency increase */ if (load > dbs_tuners_ins.up_threshold) { --- linux-source-2.6.22-2.6.22.orig/drivers/isdn/i4l/isdn_net.c +++ linux-source-2.6.22-2.6.22/drivers/isdn/i4l/isdn_net.c @@ -2126,7 +2126,7 @@ u_long flags; isdn_net_dev *p; isdn_net_phone *n; - char nr[32]; + char nr[ISDN_MSNLEN]; char *my_eaz; /* Search name in netdev-chain */ @@ -2135,7 +2135,7 @@ nr[1] = '\0'; printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n"); } else - strcpy(nr, setup->phone); + strlcpy(nr, setup->phone, ISDN_MSNLEN); si1 = (int) setup->si1; si2 = (int) setup->si2; if (!setup->eazmsn[0]) { @@ -2802,7 +2802,7 @@ chidx = -1; } } - strcpy(lp->msn, cfg->eaz); + strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn)); lp->pre_device = drvidx; lp->pre_channel = chidx; lp->onhtime = cfg->onhtime; @@ -2951,7 +2951,7 @@ if (p) { if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL))) return -ENOMEM; - strcpy(n->num, phone->phone); + strlcpy(n->num, phone->phone, sizeof(n->num)); n->next = p->local->phone[phone->outgoing & 1]; p->local->phone[phone->outgoing & 1] = n; return 0; --- linux-source-2.6.22-2.6.22.orig/drivers/isdn/i4l/isdn_common.c +++ linux-source-2.6.22-2.6.22/drivers/isdn/i4l/isdn_common.c @@ -1514,6 +1514,7 @@ if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; + iocts.drvid[sizeof(iocts.drvid)-1] = 0; if (strlen(iocts.drvid)) { if ((p = strchr(iocts.drvid, ','))) *p = 0; @@ -1598,6 +1599,7 @@ if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; + iocts.drvid[sizeof(iocts.drvid)-1] = 0; if (strlen(iocts.drvid)) { drvidx = -1; for (i = 0; i < ISDN_MAX_DRIVERS; i++) @@ -1642,7 +1644,7 @@ } else { p = (char __user *) iocts.arg; for (i = 0; i < 10; i++) { - sprintf(bname, "%s%s", + snprintf(bname, sizeof(bname), "%s%s", strlen(dev->drv[drvidx]->msn2eaz[i]) ? dev->drv[drvidx]->msn2eaz[i] : "_", (i < 9) ? "," : "\0"); @@ -1672,6 +1674,7 @@ char *p; if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) return -EFAULT; + iocts.drvid[sizeof(iocts.drvid)-1] = 0; if (strlen(iocts.drvid)) { if ((p = strchr(iocts.drvid, ','))) *p = 0; --- linux-source-2.6.22-2.6.22.orig/drivers/ieee1394/sbp2.c +++ linux-source-2.6.22-2.6.22/drivers/ieee1394/sbp2.c @@ -774,11 +774,6 @@ SBP2_ERR("failed to register lower 4GB address range"); goto failed_alloc; } -#else - if (dma_set_mask(hi->host->device.parent, DMA_32BIT_MASK)) { - SBP2_ERR("failed to set 4GB DMA mask"); - goto failed_alloc; - } #endif } --- linux-source-2.6.22-2.6.22.orig/drivers/ieee1394/ieee1394_core.c +++ linux-source-2.6.22-2.6.22/drivers/ieee1394/ieee1394_core.c @@ -1279,7 +1279,7 @@ unregister_chrdev_region(IEEE1394_CORE_DEV, 256); } -fs_initcall(ieee1394_init); /* same as ohci1394 */ +module_init(ieee1394_init); module_exit(ieee1394_cleanup); /* Exported symbols */ --- linux-source-2.6.22-2.6.22.orig/drivers/ieee1394/ohci1394.c +++ linux-source-2.6.22-2.6.22/drivers/ieee1394/ohci1394.c @@ -3773,7 +3773,5 @@ return pci_register_driver(&ohci1394_pci_driver); } -/* Register before most other device drivers. - * Useful for remote debugging via physical DMA, e.g. using firescope. */ -fs_initcall(ohci1394_init); +module_init(ohci1394_init); module_exit(ohci1394_cleanup); --- linux-source-2.6.22-2.6.22.orig/drivers/input/mouse/lifebook.c +++ linux-source-2.6.22-2.6.22/drivers/input/mouse/lifebook.c @@ -109,7 +109,7 @@ { struct lifebook_data *priv = psmouse->private; struct input_dev *dev1 = psmouse->dev; - struct input_dev *dev2 = priv->dev2; + struct input_dev *dev2 = priv ? priv->dev2 : NULL; unsigned char *packet = psmouse->packet; int relative_packet = packet[0] & 0x08; --- linux-source-2.6.22-2.6.22.orig/drivers/input/mouse/alps.c +++ linux-source-2.6.22-2.6.22/drivers/input/mouse/alps.c @@ -53,6 +53,7 @@ { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ + { { 0x73, 0x02, 0x50 }, 0xcf, 0xff, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ }; /* @@ -419,7 +420,8 @@ static int alps_reconnect(struct psmouse *psmouse) { - psmouse_reset(psmouse); + /* UBUNTU: Causes lockups on resume */ + /* psmouse_reset(psmouse); */ if (alps_hw_init(psmouse, NULL)) return -1; --- linux-source-2.6.22-2.6.22.orig/drivers/input/mouse/appletouch.c +++ linux-source-2.6.22-2.6.22/drivers/input/mouse/appletouch.c @@ -155,6 +155,8 @@ int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; int overflowwarn; /* overflow warning printed? */ int datalen; /* size of an USB urb transfer */ + int idlecount; /* number of empty packets */ + struct work_struct work; }; #define dbg_dump(msg, tab) \ @@ -208,6 +210,55 @@ (productId == GEYSER4_JIS_PRODUCT_ID); } +/* + * By default Geyser 3 device sends standard USB HID mouse + * packets (Report ID 2). This code changes device mode, so it + * sends raw sensor reports (Report ID 5). + */ +static int atp_geyser3_init(struct usb_device *udev) +{ + char data[8]; + int size; + + size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ATP_GEYSER3_MODE_READ_REQUEST_ID, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + ATP_GEYSER3_MODE_REQUEST_VALUE, + ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); + + if (size != 8) { + err("Could not do mode read request from device" + " (Geyser 3 mode)"); + return -EIO; + } + + /* Apply the mode switch */ + data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; + + size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + ATP_GEYSER3_MODE_WRITE_REQUEST_ID, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + ATP_GEYSER3_MODE_REQUEST_VALUE, + ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); + + if (size != 8) { + err("Could not do mode write request to device" + " (Geyser 3 mode)"); + return -EIO; + } + return 0; +} + +/* Reinitialise the device if it's a geyser 3 */ +static void atp_reinit(struct work_struct *work) +{ + struct atp *dev = container_of(work, struct atp, work); + struct usb_device *udev = dev->udev; + + dev->idlecount = 0; + atp_geyser3_init(udev); +} + static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, int *z, int *fingers) { @@ -276,7 +327,7 @@ static void atp_complete(struct urb* urb) { int x, y, x_z, y_z, x_f, y_f; - int retval, i, j; + int retval, i, j, key; struct atp *dev = urb->context; switch (urb->status) { @@ -418,6 +469,8 @@ y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, ATP_YFACT, &y_z, &y_f); + key = dev->data[dev->datalen - 1] & 1; + if (x && y) { if (dev->x_old != -1) { x = (dev->x_old * 3 + x) >> 2; @@ -439,9 +492,8 @@ } dev->x_old = x; dev->y_old = y; - } - else if (!x && !y) { + } else if (!x && !y) { dev->x_old = dev->y_old = -1; input_report_key(dev->input, BTN_TOUCH, 0); input_report_abs(dev->input, ABS_PRESSURE, 0); @@ -451,8 +503,22 @@ memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); } - input_report_key(dev->input, BTN_LEFT, - !!dev->data[dev->datalen - 1]); + /* Geyser 3 will continue to send packets continually after + the first touch unless reinitialised. Do so if it's been + idle for a while in order to avoid waking the kernel up + several hundred times a second */ + if (atp_is_geyser_3(dev)) { + if (!x && !y && !key) { + dev->idlecount++; + if (dev->idlecount == 10) { + dev->valid = 0; + schedule_work(&dev->work); + } + } else + dev->idlecount=0; + } + + input_report_key(dev->input, BTN_LEFT, key); input_sync(dev->input); @@ -480,6 +546,7 @@ struct atp *dev = input_get_drvdata(input); usb_kill_urb(dev->urb); + cancel_work_sync(&dev->work); dev->open = 0; } @@ -528,40 +595,10 @@ dev->datalen = 81; if (atp_is_geyser_3(dev)) { - /* - * By default Geyser 3 device sends standard USB HID mouse - * packets (Report ID 2). This code changes device mode, so it - * sends raw sensor reports (Report ID 5). - */ - char data[8]; - int size; - - size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - ATP_GEYSER3_MODE_READ_REQUEST_ID, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - - if (size != 8) { - err("Could not do mode read request from device" - " (Geyser 3 mode)"); + /* switch to raw sensor mode */ + if (atp_geyser3_init(udev)) goto err_free_devs; - } - - /* Apply the mode switch */ - data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; - - size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - ATP_GEYSER3_MODE_WRITE_REQUEST_ID, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - ATP_GEYSER3_MODE_REQUEST_VALUE, - ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); - if (size != 8) { - err("Could not do mode write request to device" - " (Geyser 3 mode)"); - goto err_free_devs; - } printk("appletouch Geyser 3 inited.\n"); } @@ -636,6 +673,8 @@ /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); + INIT_WORK(&dev->work, atp_reinit); + return 0; err_free_buffer: @@ -669,14 +708,17 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message) { struct atp *dev = usb_get_intfdata(iface); + usb_kill_urb(dev->urb); dev->valid = 0; + return 0; } static int atp_resume(struct usb_interface *iface) { struct atp *dev = usb_get_intfdata(iface); + if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) return -EIO; --- linux-source-2.6.22-2.6.22.orig/drivers/input/input.c +++ linux-source-2.6.22-2.6.22/drivers/input/input.c @@ -71,7 +71,7 @@ case EV_KEY: - if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value) + if (code > KEY_MAX || !!test_bit(code, dev->key) == value) return; if (value == 2) --- linux-source-2.6.22-2.6.22.orig/drivers/input/joystick/xpad.c +++ linux-source-2.6.22-2.6.22/drivers/input/joystick/xpad.c @@ -1,13 +1,18 @@ /* - * X-Box gamepad - v0.0.6 + * Xbox input device driver for Linux - v0.1.6 + * + * Copyright (c) 2002 - 2004 Marko Friedemann + * + * Contributors: + * Vojtech Pavlik , + * Oliver Schwartz , + * Thomas Pedley , + * Steven Toth , + * Franz Lehner , + * Ivan Hawkes + * Edgar Hucek + * Niklas Lundberg * - * Copyright (c) 2002 Marko Friedemann - * 2004 Oliver Schwartz , - * Steven Toth , - * Franz Lehner , - * Ivan Hawkes - * 2005 Dominic Cerquetti - * 2006 Adam Buchbinder * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -25,7 +30,7 @@ * * * This driver is based on: - * - information from http://euc.jp/periphs/xbox-controller.ja.html + * - information from http://euc.jp/periphs/xbox-controller.en.html * - the iForce driver drivers/char/joystick/iforce.c * - the skeleton-driver drivers/usb/usb-skeleton.c * @@ -33,116 +38,88 @@ * - ITO Takayuki for providing essential xpad information on his website * - Vojtech Pavlik - iforce driver / input subsystem * - Greg Kroah-Hartman - usb-skeleton driver - * - XBOX Linux project - extra USB id's * * TODO: - * - fine tune axes (especially trigger axes) - * - fix "analog" buttons (reported as digital now) - * - get rumble working - * - need USB IDs for other dance pads + * - fine tune axes + * - NEW: Test right thumb stick Y-axis to see if it needs flipping. + * - NEW: get rumble working correctly, fix all the bugs and support multiple + * simultaneous effects + * - NEW: split funtionality mouse/joustick into two source files + * - NEW: implement /proc interface (toggle mouse/rumble enable/disable, etc.) + * - NEW: implement user space daemon application that handles that interface * - * History: - * - * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller" - * - * 2002-07-02 - 0.0.2 : basic working version - * - all axes and 9 of the 10 buttons work (german InterAct device) - * - the black button does not work - * - * 2002-07-14 - 0.0.3 : rework by Vojtech Pavlik - * - indentation fixes - * - usb + input init sequence fixes - * - * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3 - * - verified the lack of HID and report descriptors - * - verified that ALL buttons WORK - * - fixed d-pad to axes mapping - * - * 2002-07-17 - 0.0.5 : simplified d-pad handling - * - * 2004-10-02 - 0.0.6 : DDR pad support - * - borrowed from the XBOX linux kernel - * - USB id's for commonly used dance pads are present - * - dance pads will map D-PAD to buttons, not axes - * - pass the module paramater 'dpad_to_buttons' to force - * the D-PAD to map to buttons if your pad is not detected + * History: moved to end of file */ - + #include #include #include -#include #include -#include +#include +#include +#include #include +#include +#include -#define DRIVER_VERSION "v0.0.6" -#define DRIVER_AUTHOR "Marko Friedemann " -#define DRIVER_DESC "X-Box pad driver" - -#define XPAD_PKT_LEN 32 - -/* xbox d-pads should map to buttons, as is required for DDR pads - but we map them to axes when possible to simplify things */ -#define MAP_DPAD_TO_BUTTONS 0 -#define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN -1 - -static int dpad_to_buttons; -module_param(dpad_to_buttons, bool, S_IRUGO); -MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); - -static const struct xpad_device { - u16 idVendor; - u16 idProduct; - char *name; - u8 dpad_mapping; -} xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, - { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, - { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } +#include "xpad.h" + +static unsigned long debug = 0; +module_param(debug, ulong, 0444); +MODULE_PARM_DESC(debug, "Debugging"); + +static const struct xpad_device xpad_device[] = { + /* please keep those ordered wrt. vendor/product ids + vendor, product, isMat, name, is360 */ + { 0x044f, 0x0f07, 0, "Thrustmaster, Inc. Controller", 0}, + { 0x045e, 0x0202, 0, "Microsoft Xbox Controller", 0}, + { 0x045e, 0x0285, 0, "Microsoft Xbox Controller S", 0}, + { 0x045e, 0x0287, 0, "Microsoft Xbox Controller S", 0}, + { 0x045e, 0x0289, 0, "Microsoft Xbox Controller S", 0}, /* microsoft is stupid */ + { 0x045e, 0x028e, 0, "Microsoft Xbox 360 Controller", 1}, + { 0x046d, 0xca84, 0, "Logitech Xbox Cordless Controller", 0}, + { 0x046d, 0xca88, 0, "Logitech Compact Controller for Xbox", 0}, + { 0x05fd, 0x1007, 0, "???Mad Catz Controller???", 0}, /* CHECKME: this seems strange */ + { 0x05fd, 0x107a, 0, "InterAct PowerPad Pro", 0}, + { 0x0738, 0x4516, 0, "Mad Catz Control Pad", 0}, + { 0x0738, 0x4522, 0, "Mad Catz LumiCON", 0}, + { 0x0738, 0x4526, 0, "Mad Catz Control Pad Pro", 0}, + { 0x0738, 0x4536, 0, "Mad Catz MicroCON", 0}, + { 0x0738, 0x4540, 1, "Mad Catz Beat Pad", 0}, + { 0x0738, 0x4556, 0, "Mad Catz Lynx Wireless Controller", 0}, + { 0x0738, 0x6040, 1, "Mad Catz Beat Pad Pro", 0}, + { 0x0c12, 0x8802, 0, "Zeroplus Xbox Controller", 0}, + { 0x0c12, 0x8809, 0, "Level Six Xbox DDR Dancepad", 0}, + { 0x0c12, 0x8810, 0, "Zeroplus Xbox Controller", 0}, + { 0x0c12, 0x9902, 0, "HAMA VibraX - *FAULTY HARDWARE*", 0}, /* these are broken */ + { 0x0e4c, 0x1097, 0, "Radica Gamester Controller", 0}, + { 0x0e4c, 0x2390, 0, "Radica Games Jtech Controller", 0}, + { 0x0e6f, 0x0003, 0, "Logic3 Freebird wireless Controller", 0}, + { 0x0e6f, 0x0005, 0, "Eclipse wireless Controller", 0}, + { 0x0e6f, 0x0006, 0, "Edge wireless Controller", 0}, + { 0x0e6f, 0x000c, 0, "PELICAN PL-2047", 0}, + { 0x0e8f, 0x0201, 0, "SmartJoy Frag Xpad/PS2 adaptor", 0}, + { 0x0f30, 0x0202, 0, "Joytech Advanced Controller", 0}, + { 0x0f30, 0x8888, 0, "BigBen XBMiniPad Controller", 0}, + { 0x102c, 0xff0c, 0, "Joytech Wireless Advanced Controller", 0}, + { 0x12ab, 0x8809, 1, "Xbox DDR dancepad", 0}, + { 0xffff, 0xffff, 0, "Chinese-made Xbox Controller", 0}, /* WTF are device IDs for? */ + { 0x0000, 0x0000, 0, "nothing detected - FAIL", 0} }; static const signed short xpad_btn[] = { - BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ + BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* analogue buttons */ BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ + BTN_0, BTN_1, BTN_2, BTN_3, /* d-pad as buttons */ + BTN_TL, BTN_TR, /* Button LB/RB */ + BTN_MODE, /* The big X */ -1 /* terminating entry */ }; -/* only used if MAP_DPAD_TO_BUTTONS */ -static const signed short xpad_btn_pad[] = { - BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ - BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ +static const signed short xpad_mat_btn[] = { + BTN_A, BTN_B, BTN_X, BTN_Y, /* A, B, X, Y */ + BTN_START, BTN_BACK, /* start/back */ + BTN_0, BTN_1, BTN_2, BTN_3, /* directions */ -1 /* terminating entry */ }; @@ -150,91 +127,133 @@ ABS_X, ABS_Y, /* left stick */ ABS_RX, ABS_RY, /* right stick */ ABS_Z, ABS_RZ, /* triggers left/right */ - -1 /* terminating entry */ -}; - -/* only used if MAP_DPAD_TO_AXES */ -static const signed short xpad_abs_pad[] = { - ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ + ABS_HAT0X, ABS_HAT0Y, /* digital pad */ + ABS_HAT1X, ABS_HAT1Y, /* analogue buttons A + B */ + ABS_HAT2X, ABS_HAT2Y, /* analogue buttons C + X */ + ABS_HAT3X, ABS_HAT3Y, /* analogue buttons Y + Z */ -1 /* terminating entry */ }; static struct usb_device_id xpad_table [] = { - { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ + { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not approved class */ + { USB_INTERFACE_INFO( 3 , 0 , 0) }, /* for Joytech Advanced Controller */ + { USB_INTERFACE_INFO( 255 , 93 , 1) }, /* Xbox 360 */ { } }; -MODULE_DEVICE_TABLE (usb, xpad_table); - -struct usb_xpad { - struct input_dev *dev; /* input device interface */ - struct usb_device *udev; /* usb device */ - - struct urb *irq_in; /* urb for interrupt in report */ - unsigned char *idata; /* input data */ - dma_addr_t idata_dma; +MODULE_DEVICE_TABLE(usb, xpad_table); - char phys[65]; /* physical device path */ - - int dpad_mapping; /* map d-pad to buttons or to axes */ -}; - -/* +/** * xpad_process_packet * - * Completes a request by converting the data into events for the - * input subsystem. + * Completes a request by converting the data into events + * for the input subsystem. * - * The used report descriptor was taken from ITO Takayukis website: - * http://euc.jp/periphs/xbox-controller.ja.html + * The report descriptor was taken from ITO Takayukis website: + * http://euc.jp/periphs/xbox-controller.en.html */ - static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; + int i; + + if(debug) { + printk(KERN_INFO "xpad_debug: data :"); + for(i = 0; i < 20; i++) { + printk("0x%02x ", data[i]); + } + printk("\n"); + } + + /* digital pad (button mode) bits (3 2 1 0) (right left down up) */ + input_report_key(dev, BTN_0, (data[2] & 0x01)); + input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3); + input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1); + input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2); + + /* start and back buttons */ + input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); + input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); + + /* stick press left/right */ + input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); + input_report_key(dev, BTN_THUMBR, data[2] >> 7); + + /* buttons A, B, X, Y digital mode */ + if(xpad->is360) { + input_report_key(dev, BTN_A, (data[3] & 0x10) >> 4); + input_report_key(dev, BTN_B, (data[3] & 0x20) >> 5); + input_report_key(dev, BTN_X, (data[3] & 0x80) >> 7); + input_report_key(dev, BTN_Y, (data[3] & 0x40) >> 6); + input_report_key(dev, BTN_TL, data[3] & 0x01 ); + input_report_key(dev, BTN_TR, (data[3] & 0x02) >> 1); + input_report_key(dev, BTN_MODE, (data[3] & 0x04) >> 2); + } else { + input_report_key(dev, BTN_A, data[4]); + input_report_key(dev, BTN_B, data[5]); + input_report_key(dev, BTN_X, data[6]); + input_report_key(dev, BTN_Y, data[7]); + } + + if (xpad->isMat) + return; - /* left stick */ - input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); - input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14])); + /* left stick (Y axis needs to be flipped) */ + if(xpad->is360) { + input_report_abs(dev, ABS_X, (__s16)(((__s16)data[7] << 8) | (__s16)data[6])); + input_report_abs(dev, ABS_Y, ~(__s16)(((__s16)data[9] << 8) | data[8])); + } else { + input_report_abs(dev, ABS_X, (__s16)(((__s16)data[13] << 8) | (__s16)data[12])); + input_report_abs(dev, ABS_Y, ~(__s16)(((__s16)data[15] << 8) | data[14])); + } /* right stick */ - input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16])); - input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18])); + if(xpad->is360) { + input_report_abs(dev, ABS_RX, (__s16)(((__s16)data[13] << 8) | (__s16)data[12])); + input_report_abs(dev, ABS_RY, (__s16)(((__s16)data[11] << 8) | (__s16)data[10])); + } else { + input_report_abs(dev, ABS_RX, (__s16)(((__s16)data[17] << 8) | (__s16)data[16])); + input_report_abs(dev, ABS_RY, (__s16)(((__s16)data[19] << 8) | (__s16)data[18])); + } /* triggers left/right */ - input_report_abs(dev, ABS_Z, data[10]); - input_report_abs(dev, ABS_RZ, data[11]); + if(xpad->is360) { + input_report_abs(dev, ABS_Z, data[4]); + input_report_abs(dev, ABS_RZ, data[5]); + } else { + input_report_abs(dev, ABS_Z, data[10]); + input_report_abs(dev, ABS_RZ, data[11]); + } - /* digital pad */ - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { + if(!xpad->is360) { + /* digital pad (analogue mode): bits (3 2 1 0) (right left down up) */ input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); - } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { - input_report_key(dev, BTN_LEFT, data[2] & 0x04); - input_report_key(dev, BTN_RIGHT, data[2] & 0x08); - input_report_key(dev, BTN_0, data[2] & 0x01); // up - input_report_key(dev, BTN_1, data[2] & 0x02); // down - } - - /* start/back buttons and stick press left/right */ - input_report_key(dev, BTN_START, data[2] & 0x10); - input_report_key(dev, BTN_BACK, data[2] & 0x20); - input_report_key(dev, BTN_THUMBL, data[2] & 0x40); - input_report_key(dev, BTN_THUMBR, data[2] & 0x80); - - /* "analog" buttons A, B, X, Y */ - input_report_key(dev, BTN_A, data[4]); - input_report_key(dev, BTN_B, data[5]); - input_report_key(dev, BTN_X, data[6]); - input_report_key(dev, BTN_Y, data[7]); - - /* "analog" buttons black, white */ - input_report_key(dev, BTN_C, data[8]); - input_report_key(dev, BTN_Z, data[9]); + input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x01) - !!(data[2] & 0x02)); + + /* button A, B, X, Y analogue mode */ + input_report_abs(dev, ABS_HAT1X, data[4]); + input_report_abs(dev, ABS_HAT1Y, data[5]); + input_report_abs(dev, ABS_HAT2Y, data[6]); + input_report_abs(dev, ABS_HAT3X, data[7]); + + /* button C (black) digital/analogue mode */ + input_report_key(dev, BTN_C, data[8]); + input_report_abs(dev, ABS_HAT2X, data[8]); + + /* button Z (white) digital/analogue mode */ + input_report_key(dev, BTN_Z, data[9]); + input_report_abs(dev, ABS_HAT3Y, data[9]); + } input_sync(dev); } +/** + * xpad_irq_in + * + * Completion handler for interrupt in transfers (user input). + * Just calls xpad_process_packet which does then emit input events. + */ static void xpad_irq_in(struct urb *urb) { struct usb_xpad *xpad = urb->context; @@ -248,77 +267,96 @@ case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); goto exit; } xpad_process_packet(xpad, 0, xpad->idata); exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); + retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + err("%s - usb_submit_urb failed with result %d", + __FUNCTION__, retval); } -static int xpad_open (struct input_dev *dev) +/** + * xpad_open + * + * Called when a an application opens the device. + */ +static int xpad_open(struct input_dev *dev) { - struct usb_xpad *xpad = input_get_drvdata(dev); + struct usb_xpad *xpad = dev->private; + int status; + + info("opening device"); xpad->irq_in->dev = xpad->udev; - if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) + if ((status = usb_submit_urb(xpad->irq_in, GFP_KERNEL))) { + err("open input urb failed: %d", status); return -EIO; + } + + if(!xpad->is360) { + xpad_rumble_open(xpad); + } return 0; } -static void xpad_close (struct input_dev *dev) +/** + * xpad_close + * + * Called when an application closes the device. + */ +static void xpad_close(struct input_dev *dev) { struct usb_xpad *xpad = input_get_drvdata(dev); + info("closing device"); usb_kill_urb(xpad->irq_in); -} - -static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) -{ - set_bit(abs, input_dev->absbit); - - switch (abs) { - case ABS_X: - case ABS_Y: - case ABS_RX: - case ABS_RY: /* the two sticks */ - input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); - break; - case ABS_Z: - case ABS_RZ: /* the triggers */ - input_set_abs_params(input_dev, abs, 0, 255, 0, 0); - break; - case ABS_HAT0X: - case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ - input_set_abs_params(input_dev, abs, -1, 1, 0, 0); - break; + if(!xpad->is360) { + xpad_rumble_close(xpad); } } +/** + * xpad_probe + * + * Called upon device detection to find a suitable driver. + * Must return NULL when no xpad is found, else setup everything. + */ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev (intf); + struct usb_device *udev = interface_to_usbdev(intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i; int error = -ENOMEM; + int probedDevNum = -1; /* this takes the index into the known devices + array for the recognized device */ - for (i = 0; xpad_device[i].idVendor; i++) { + /* try to detect the device we are called for */ + for (i = 0; xpad_device[i].idVendor; ++i) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && - (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) + (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) { + probedDevNum = i; break; + } } + /* sanity check, did we recognize this device? if not, fail */ + if ((probedDevNum == -1) || (!xpad_device[probedDevNum].idVendor && + !xpad_device[probedDevNum].idProduct)) + return -ENODEV; + xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) @@ -329,19 +367,19 @@ if (!xpad->idata) goto fail1; + /* setup input interrupt pipe (button and axis state) */ xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) goto fail2; xpad->udev = udev; - xpad->dpad_mapping = xpad_device[i].dpad_mapping; - if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) - xpad->dpad_mapping = dpad_to_buttons; xpad->dev = input_dev; + xpad->isMat = xpad_device[probedDevNum].isMat; + xpad->is360 = xpad_device[probedDevNum].is360; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); - input_dev->name = xpad_device[i].name; + input_dev->name = xpad_device[probedDevNum].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; @@ -351,22 +389,61 @@ input_dev->open = xpad_open; input_dev->close = xpad_close; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - - /* set up buttons */ - for (i = 0; xpad_btn[i] >= 0; i++) - set_bit(xpad_btn[i], input_dev->keybit); - if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) - for (i = 0; xpad_btn_pad[i] >= 0; i++) - set_bit(xpad_btn_pad[i], input_dev->keybit); - - /* set up axes */ - for (i = 0; xpad_abs[i] >= 0; i++) - xpad_set_up_abs(input_dev, xpad_abs[i]); - if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) - for (i = 0; xpad_abs_pad[i] >= 0; i++) - xpad_set_up_abs(input_dev, xpad_abs_pad[i]); + /* this was meant to allow a user space tool on-the-fly configuration + of driver options (rumble on, etc...) + yet, Vojtech said this is better done using sysfs (linux 2.6) + plus, it needs a patch to the input subsystem */ +/* input_dev->ioctl = xpad_ioctl;*/ + + if (xpad->isMat) { + input_dev->evbit[0] = BIT(EV_KEY); + for (i = 0; xpad_mat_btn[i] >= 0; ++i) + set_bit(xpad_mat_btn[i], input_dev->keybit); + } else { + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + + for (i = 0; xpad_btn[i] >= 0; ++i) + set_bit(xpad_btn[i], input_dev->keybit); + + for (i = 0; xpad_abs[i] >= 0; ++i) { + + signed short t = xpad_abs[i]; + + set_bit(t, input_dev->absbit); + + switch (t) { + case ABS_X: + case ABS_Y: + case ABS_RX: + case ABS_RY: /* the two sticks */ + input_set_abs_params(input_dev, t, + -32768, 32767, 16, 12000); + break; + case ABS_Z: /* left trigger */ + case ABS_RZ: /* right trigger */ + case ABS_HAT1X: /* analogue button A */ + case ABS_HAT1Y: /* analogue button B */ + case ABS_HAT2X: /* analogue button C */ + case ABS_HAT2Y: /* analogue button X */ + case ABS_HAT3X: /* analogue button Y */ + case ABS_HAT3Y: /* analogue button Z */ + input_set_abs_params(input_dev, t, + 0, 255, 0, 0); + break; + case ABS_HAT0X: + case ABS_HAT0Y: /* the d-pad */ + input_set_abs_params(input_dev, t, + -1, 1, 0, 0); + break; + } + } + + if (!xpad->is360) + if (xpad_rumble_probe(udev, xpad, ifnum) != 0) + err("could not init rumble"); + } + /* init input URB for USB INT transfer from device */ ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -380,31 +457,56 @@ goto fail3; usb_set_intfdata(intf, xpad); + + /* Turn off the LEDs on xpad 360 controllers */ + if (xpad->is360) { + char ledcmd[] = {1, 3, 0}; /* The LED-off command for Xbox-360 controllers */ + int j; + usb_bulk_msg(udev, usb_sndintpipe(udev,2), ledcmd, 3, &j, 0); + } + return 0; - fail3: usb_free_urb(xpad->irq_in); - fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - fail1: input_free_device(input_dev); +fail3: usb_free_urb(xpad->irq_in); +fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); +fail1: input_free_device(input_dev); kfree(xpad); return error; - } +/** + * xpad_disconnect + * + * Called upon device disconnect to dispose of the structures and + * close the USB connections. + */ static void xpad_disconnect(struct usb_interface *intf) { - struct usb_xpad *xpad = usb_get_intfdata (intf); + struct usb_xpad *xpad = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); if (xpad) { usb_kill_urb(xpad->irq_in); + if(!xpad->is360) { + xpad_rumble_close(xpad); + } input_unregister_device(xpad->dev); + usb_free_urb(xpad->irq_in); + usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); + + if(!xpad->is360) { + xpad_rumble_disconnect(xpad); + } + kfree(xpad); } } +/******************* Linux driver framework specific stuff ************/ + static struct usb_driver xpad_driver = { .name = "xpad", .probe = xpad_probe, @@ -412,14 +514,20 @@ .id_table = xpad_table, }; +/** + * driver init entry point + */ static int __init usb_xpad_init(void) { int result = usb_register(&xpad_driver); if (result == 0) - info(DRIVER_DESC ":" DRIVER_VERSION); + info(DRIVER_DESC " " DRIVER_VERSION); return result; } +/** + * driver exit entry point + */ static void __exit usb_xpad_exit(void) { usb_deregister(&xpad_driver); @@ -431,3 +539,60 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); + +/* + * driver history + * ---------------- + * + * 2005-11-25 - 0.1.6 : Added Xbox 360 Controller support + * + * 2005-03-15 - 0.1.5 : Mouse emulation removed. Deadzones increased. + * - Flipped the Y axis of the left joystick (it was inverted, like on a + * flight simulator). + * + * 2003-05-15 - 0.1.2 : ioctls, dynamic mouse/rumble activation, /proc fs + * - added some /proc files for informational purposes (readonly right now) + * - added init parameters for mouse/rumble activation upon detection + * - added dynamic changes to mouse events / rumble effect generation via + * ioctls - NOTE: this requires a currently unofficial joydev patch! + * + * 2003-04-29 - 0.1.1 : minor cleanups, some comments + * - fixed incorrect handling of unknown devices (please try ir dongle now) + * - fixed input URB length (the 256 bytes from 0.1.0 broke everything for the + * MS controller as well as my Interact device, set back to 32 (please + * REPORT problems BEFORE any further changes here, since those can be fatal) + * - fixed rumbling for MS controllers (need 6 bytes output report) + * - dropped kernel-2.5 ifdefs, much more readable now + * - preparation for major rework under way, stay tuned + * + * 2003-03-25 - 0.1.0 : (Franz) Some Debuggin + * - Better Handling + * - X/Y support, Speed differenting + * - Landing Zone, Dead Zone, Offset kompensation, Zero-adjustment, .... aso. + * - Removed Wheel handling in Mouse Emulation .. sensless.. + * + * 2003-01-23 - 0.1.0-pre : added mouse emulation and rumble support + * - can provide mouse emulation (compile time switch) + * this code has been taken from Oliver Schwartz' xpad-mouse driver + * - basic rumble support (compile time switch) EXPERIMENTAL! + * + * 2002-08-05 - 0.0.6 : added analog button support + * + * 2002-07-17 - 0.0.5 : (Vojtech Pavlik) rework + * - simplified d-pad handling + * + * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3 + * - verified the lack of HID and report descriptors + * - verified that ALL buttons WORK + * - fixed d-pad to axes mapping + * + * 2002-07-14 - 0.0.3 : (Vojtech Pavlik) rework + * - indentation fixes + * - usb + input init sequence fixes + * + * 2002-07-02 - 0.0.2 : basic working version + * - all axes and 9 of the 10 buttons work (german InterAct device) + * - the black button does not work + * + * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller" + */ --- linux-source-2.6.22-2.6.22.orig/drivers/input/joystick/xpad.h +++ linux-source-2.6.22-2.6.22/drivers/input/joystick/xpad.h @@ -0,0 +1,131 @@ +/* + * Xbox Controller driver for Linux - v0.1.5 + * + * header file containing ioctl definitions + * + * Copyright (c) 2003 Marko Friedemann + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __XPAD_h +#define __XPAD_h + + +/*********** ioctl stuff, can be used outside of the driver ***********/ +#define USB_XPAD_IOC_MAGIC 'x' + +#define USB_XPAD_IOCRESET _IO( USB_XPAD_IOC_MAGIC, 0 ) +#define USB_XPAD_IOCSRUMBLE _IOW( USB_XPAD_IOC_MAGIC, 3, int ) +#define USB_XPAD_IOCGRUMBLE _IOR( USB_XPAD_IOC_MAGIC, 4, int ) + +#define USB_XPAD_IOCSIR _IOW( USB_XPAD_IOC_MAGIC, 5, int ) +#define USB_XPAD_IOCGIR _IOR( USB_XPAD_IOC_MAGIC, 6, int ) + +#define USB_XPAD_IOC_MAXNR 6 + +/************************* driver internals ***************************/ +#ifdef __KERNEL__ + +#include +#include + +/****************** driver description and version ********************/ +#define DRIVER_VERSION "v0.1.6" +#define DRIVER_AUTHOR "Marko Friedemann ,\ + Oliver Schwartz , Georg Lukas ,\ + Thomas Pedley , Edgar Hucek " + +#define DRIVER_DESC "driver for Xbox controllers" + +/****************************** constants *****************************/ +#define XPAD_MAX_DEVICES 4 +#define XPAD_PKT_LEN 32 /* input packet size */ +#define XPAD_PKT_LEN_FF 6 /* output packet size - rumble */ + +#define XPAD_TX_BUFSIZE XPAD_PKT_LEN_FF * 8 /* max. 8 requests */ + +/************************* the device struct **************************/ +struct usb_xpad { + struct input_dev *dev; /* input device interface */ + struct usb_device *udev; /* usb device */ + + struct urb *irq_in; /* urb for int. in report */ + unsigned char *idata; /* input data */ + dma_addr_t idata_dma; + + char phys[65]; /* physical input dev path */ + + unsigned char offsetset_compensation; + int left_offset_x; + int left_offset_y; + int right_offset_x; + int right_offset_y; + + int isMat; /* is this a dancepad/mat? */ + int is360; /* is this a Xbox 360 Controller */ + +#ifdef CONFIG_USB_XPAD_RUMBLE + int rumble_enabled; /* ioctl can toggle rumble */ + + int ep_out_adr; /* number of out endpoint */ + unsigned char tx_data[XPAD_PKT_LEN_FF]; /* output data (rumble) */ + int strong_rumble, play_strong; /* strong rumbling */ + int weak_rumble, play_weak; /* weak rumbling */ + struct timer_list rumble_timer; /* timed urb out retry */ + wait_queue_head_t wait; /* wait for URBs on queue */ + + spinlock_t tx_lock; + struct circ_buf tx; + unsigned char tx_buf[XPAD_TX_BUFSIZE]; + long tx_flags[1]; /* transmit flags */ +#endif +}; + +/* for the list of know devices */ +struct xpad_device { + u16 idVendor; + u16 idProduct; + u8 isMat; + char *name; + u8 is360; +}; + + +/************************ rumble function stubs ***********************/ +#ifndef CONFIG_USB_XPAD_RUMBLE + #define xpad_rumble_ioctl(dev, cmd, arg) -ENOTTY + #define xpad_rumble_open(xpad) {} + #define xpad_rumble_probe(udev, xpad, ifnum) 0 + #define xpad_rumble_close(xpad) {} + #define xpad_rumble_disconnect(xpad) {} +#else /* CONFIG_USB_XPAD_RUMBLE */ + + #define XPAD_TX_RUNNING 0 + #define XPAD_TX_INC(var, n) (var) += n; (var) %= XPAD_TX_BUFSIZE + + #ifndef __USB_XPAD_RUMBLE + extern int xpad_rumble_ioctl(struct input_dev *dev, unsigned int cmd, unsigned long arg); + extern void xpad_rumble_open(struct usb_xpad *xpad); + extern int xpad_rumble_probe(struct usb_device *udev, struct usb_xpad *xpad, unsigned int ifnum); + extern void xpad_rumble_close(struct usb_xpad *xpad); + extern void xpad_rumble_disconnect(struct usb_xpad *xpad); + #endif /* __USB_XPAD_RUMBLE */ +#endif /* CONFIG_USB_XPAD_RUMBLE */ + +#endif /* __KERNEL__ */ + +#endif /* __XPAD_h */ --- linux-source-2.6.22-2.6.22.orig/drivers/input/touchscreen/Makefile +++ linux-source-2.6.22-2.6.22/drivers/input/touchscreen/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o +obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o --- linux-source-2.6.22-2.6.22.orig/drivers/input/touchscreen/fujitsu_ts.c +++ linux-source-2.6.22-2.6.22/drivers/input/touchscreen/fujitsu_ts.c @@ -0,0 +1,189 @@ +/* + * Fujitsu serial touchscreen driver + * + * Copyright (c) Dmitry Torokhov + */ + +/* + * 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 +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "Fujitsu serial touchscreen driver" + +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +#define FUJITSU_LENGTH 5 + +/* + * Per-touchscreen data. + */ +struct fujitsu { + struct input_dev *dev; + struct serio *serio; + int idx; + unsigned char data[FUJITSU_LENGTH]; + char phys[32]; +}; + +/* + * Decode serial data (5 bytes per packet) + * First byte + * 1 C 0 0 R S S S + * Where C is 1 while in calibration mode (which we don't use) + * R is 1 when no coordinate corection was done. + * S are button state + */ +static irqreturn_t fujitsu_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) +{ + struct fujitsu *fujitsu = serio_get_drvdata(serio); + struct input_dev *dev = fujitsu->dev; + + if (fujitsu->idx == 0) { + /* resync skip until start of frame */ + if ((data & 0xf0) != 0x80) + return IRQ_HANDLED; + } else { + /* resync skip garbage */ + if (data & 0x80) { + fujitsu->idx = 0; + return IRQ_HANDLED; + } + } + + fujitsu->data[fujitsu->idx++] = data; + if (fujitsu->idx == FUJITSU_LENGTH) { + input_report_abs(dev, ABS_X, + (fujitsu->data[2] << 7) | fujitsu->data[1]); + input_report_abs(dev, ABS_Y, + (fujitsu->data[4] << 7) | fujitsu->data[3]); + input_report_key(dev, BTN_TOUCH, + (fujitsu->data[0] & 0x03) != 2); + input_sync(dev); + fujitsu->idx = 0; + } + + return IRQ_HANDLED; +} + +/* + * fujitsu_disconnect() is the opposite of fujitsu_connect() + */ +static void fujitsu_disconnect(struct serio *serio) +{ + struct fujitsu *fujitsu = serio_get_drvdata(serio); + + input_get_device(fujitsu->dev); + input_unregister_device(fujitsu->dev); + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_put_device(fujitsu->dev); + kfree(fujitsu); +} + +/* + * fujitsu_connect() is the routine that is called when someone adds a + * new serio device that supports the Fujitsu protocol and registers it + * as input device. + */ +static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) +{ + struct fujitsu *fujitsu; + struct input_dev *input_dev; + int err; + + fujitsu = kzalloc(sizeof(struct fujitsu), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!fujitsu || !input_dev) { + err = -ENOMEM; + goto fail1; + } + + fujitsu->serio = serio; + fujitsu->dev = input_dev; + snprintf(fujitsu->phys, sizeof(fujitsu->phys), + "%s/input0", serio->phys); + + input_dev->name = "Fujitsu Serial Touchscreen"; + input_dev->phys = fujitsu->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_FUJITSU; + input_dev->id.product = 0; + input_dev->id.version = 0x0100; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0); + serio_set_drvdata(serio, fujitsu); + + err = serio_open(serio, drv); + if (err) + goto fail2; + + err = input_register_device(fujitsu->dev); + if (err) + goto fail3; + + return 0; + + fail3: + serio_close(serio); + fail2: + serio_set_drvdata(serio, NULL); + fail1: + input_free_device(input_dev); + kfree(fujitsu); + return err; +} + +/* + * The serio driver structure. + */ +static struct serio_device_id fujitsu_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_FUJITSU, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, fujitsu_serio_ids); + +static struct serio_driver fujitsu_drv = { + .driver = { + .name = "fujitsu_ts", + }, + .description = DRIVER_DESC, + .id_table = fujitsu_serio_ids, + .interrupt = fujitsu_interrupt, + .connect = fujitsu_connect, + .disconnect = fujitsu_disconnect, +}; + +static int __init fujitsu_init(void) +{ + return serio_register_driver(&fujitsu_drv); +} + +static void __exit fujitsu_exit(void) +{ + serio_unregister_driver(&fujitsu_drv); +} + +module_init(fujitsu_init); +module_exit(fujitsu_exit); --- linux-source-2.6.22-2.6.22.orig/drivers/input/touchscreen/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/input/touchscreen/Kconfig @@ -54,6 +54,19 @@ To compile this driver as a module, choose M here: the module will be called corgi_ts. +config TOUCHSCREEN_FUJITSU + tristate "Fujitsu serial touchscreen" + select SERIO + help + Say Y here if you have the Fujitsu touchscreen (such as one + installed in Lifebook P series laptop) connected to your + system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called fujitsu-ts. + config TOUCHSCREEN_GUNZE tristate "Gunze AHL-51S touchscreen" select SERIO --- linux-source-2.6.22-2.6.22.orig/drivers/pci/msi.c +++ linux-source-2.6.22-2.6.22/drivers/pci/msi.c @@ -23,7 +23,7 @@ #include "pci.h" #include "msi.h" -static int pci_msi_enable = 1; +static int pci_msi_enable = 0; static void msi_set_enable(struct pci_dev *dev, int enable) { @@ -673,6 +673,11 @@ pci_msi_enable = 0; } +void pci_yes_msi(void) +{ + pci_msi_enable = 1; +} + void pci_msi_init_pci_dev(struct pci_dev *dev) { INIT_LIST_HEAD(&dev->msi_list); --- linux-source-2.6.22-2.6.22.orig/drivers/pci/probe.c +++ linux-source-2.6.22-2.6.22/drivers/pci/probe.c @@ -643,20 +643,20 @@ sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + /* Has only triggered on CardBus, fixup is in yenta_socket */ while (bus->parent) { if ((child->subordinate > bus->subordinate) || (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " - "hidden behind%s bridge #%02x (-#%02x)%s\n", - child->number, child->subordinate, - bus->self->transparent ? " transparent" : " ", - bus->number, bus->subordinate, - pcibios_assign_all_busses() ? " " : - " (try 'pci=assign-busses')"); - printk(KERN_WARNING "Please report the result to " - "linux-kernel to fix this permanently\n"); + pr_debug("PCI: Bus #%02x (-#%02x) is %s" + "hidden behind%s bridge #%02x (-#%02x)\n", + child->number, child->subordinate, + (bus->number > child->subordinate && + bus->subordinate < child->number) ? + "wholly " : " partially", + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate); } bus = bus->parent; } --- linux-source-2.6.22-2.6.22.orig/drivers/pci/pci.c +++ linux-source-2.6.22-2.6.22/drivers/pci/pci.c @@ -1409,6 +1409,8 @@ if (*str && (str = pcibios_setup(str)) && *str) { if (!strcmp(str, "nomsi")) { pci_no_msi(); + } else if (!strcmp(str, "msi")) { + pci_yes_msi(); } else if (!strncmp(str, "cbiosize=", 9)) { pci_cardbus_io_size = memparse(str + 9, &str); } else if (!strncmp(str, "cbmemsize=", 10)) { @@ -1427,6 +1429,7 @@ device_initcall(pci_init); EXPORT_SYMBOL_GPL(pci_restore_bars); +EXPORT_SYMBOL(__pci_reenable_device); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pcim_enable_device); --- linux-source-2.6.22-2.6.22.orig/drivers/pci/pci.h +++ linux-source-2.6.22-2.6.22/drivers/pci/pci.h @@ -1,6 +1,5 @@ /* Functions internal to the PCI core code */ -extern int __must_check __pci_reenable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); @@ -47,9 +46,11 @@ #ifdef CONFIG_PCI_MSI void pci_no_msi(void); +void pci_yes_msi(void); extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } +static inline void pci_yes_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif --- linux-source-2.6.22-2.6.22.orig/drivers/pci/quirks.c +++ linux-source-2.6.22-2.6.22/drivers/pci/quirks.c @@ -187,10 +187,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691_0, quirk_vialatency ); /* Must restore this on a resume from RAM */ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691_0, quirk_vialatency ); /* * VIA Apollo VP3 needs ETBF on BT848/878 @@ -1490,6 +1492,17 @@ } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); + +static void __devinit fixup_poulsbo_hda(struct pci_dev *dev) +{ + /* poulsbo A2 HD audio controller has the wrong class type of 604h */ + if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) { + printk(KERN_INFO "Poulsbo A2 HDA detected, setting PCI class.\n"); + dev->class = PCI_CLASS_MULTIMEDIA_AUDIO; + } +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_POULSBO_HDA, fixup_poulsbo_hda); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { while (f < end) { @@ -1640,6 +1653,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ @@ -1719,3 +1735,35 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); #endif /* CONFIG_PCI_MSI */ + +/* The Intel Poulsbo chipset pata controller IDE decode enable bit holds default + * value -- it will always be 0. Actually on current stepping, this quirk + * function won't work either (write to this bit has no effect). But we still + * put it here, may for upcoming steppings. + */ +static void __devinit quirk_intel_poulsbo_ide_enable(struct pci_dev *dev) +{ + unsigned char value; + + pci_read_config_byte(dev, 0x41, &value); + if (!(value & 0x80)) { + printk(KERN_DEBUG "PCI: PIIX4: Fixing " + "Poulsbo PATA port 1 IDE decode enabling bit\n"); + value |= 0x80; + pci_write_config_byte(dev, 0x41, value); + pci_read_config_byte(dev, 0x41, &value); + printk(KERN_DEBUG "Re-read enabling bit:%d\n", value); + } + pci_read_config_byte(dev, 0x43, &value); + if (!(value & 0x80)) { + printk(KERN_DEBUG "PCI: PIIX4: Fixing " + "Poulsbo PATA port 2 IDE decode enabling bit\n"); + value |= 0x80; + pci_write_config_byte(dev, 0x43, value); + pci_read_config_byte(dev, 0x43, &value); + printk(KERN_DEBUG "Re-read enabling bit:%d\n", value); + } +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_POULSBO_IDE, + quirk_intel_poulsbo_ide_enable); --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-snap.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-snap.c @@ -522,9 +522,12 @@ /* Metadata must only be loaded into one table at once */ r = s->store.read_metadata(&s->store); - if (r) { + if (r < 0) { ti->error = "Failed to read snapshot metadata"; goto bad6; + } else if (r > 0) { + s->valid = 0; + DMWARN("Snapshot is marked invalid."); } bio_list_init(&s->queued_bios); @@ -884,9 +887,6 @@ if (!s->valid) return -EIO; - if (unlikely(bio_barrier(bio))) - return -EOPNOTSUPP; - /* FIXME: should only take write lock if we need * to copy an exception */ down_write(&s->lock); @@ -1157,9 +1157,6 @@ struct dm_dev *dev = (struct dm_dev *) ti->private; bio->bi_bdev = dev->bdev; - if (unlikely(bio_barrier(bio))) - return -EOPNOTSUPP; - /* Only tell snapshots if this is a write */ return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; } --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm.c @@ -802,6 +802,15 @@ int rw = bio_data_dir(bio); struct mapped_device *md = q->queuedata; + /* + * There is no use in forwarding any barrier request since we can't + * guarantee it is (or can be) handled by the targets correctly. + */ + if (unlikely(bio_barrier(bio))) { + bio_endio(bio, bio->bi_size, -EOPNOTSUPP); + return 0; + } + down_read(&md->io_lock); disk_stat_inc(dm_disk(md), ios[rw]); --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-raid1.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-raid1.c @@ -1288,12 +1288,12 @@ for (m = 0; m < ms->nr_mirrors; m++) DMEMIT("%s ", ms->mirror[m].dev->name); - DMEMIT("%llu/%llu", + DMEMIT("%llu/%llu 0 ", (unsigned long long)ms->rh.log->type-> get_sync_count(ms->rh.log), (unsigned long long)ms->nr_regions); - sz = ms->rh.log->type->status(ms->rh.log, type, result, maxlen); + sz += ms->rh.log->type->status(ms->rh.log, type, result+sz, maxlen-sz); break; --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-crypt.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-crypt.c @@ -920,6 +920,8 @@ { struct crypt_config *cc = (struct crypt_config *) ti->private; + flush_workqueue(_kcryptd_workqueue); + bioset_free(cc->bs); mempool_destroy(cc->page_pool); mempool_destroy(cc->io_pool); @@ -941,9 +943,6 @@ struct crypt_config *cc = ti->private; struct crypt_io *io; - if (bio_barrier(bio)) - return -EOPNOTSUPP; - io = mempool_alloc(cc->io_pool, GFP_NOIO); io->target = ti; io->base_bio = bio; --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-exception-store.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-exception-store.c @@ -457,11 +457,6 @@ /* * Sanity checks. */ - if (!ps->valid) { - DMWARN("snapshot is marked invalid"); - return -EINVAL; - } - if (ps->version != SNAPSHOT_DISK_VERSION) { DMWARN("unable to handle snapshot disk version %d", ps->version); @@ -469,6 +464,12 @@ } /* + * Metadata are valid, but snapshot is invalidated + */ + if (!ps->valid) + return 1; + + /* * Read the metadata. */ r = read_exceptions(ps); --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-mpath.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-mpath.c @@ -798,9 +798,6 @@ struct mpath_io *mpio; struct multipath *m = (struct multipath *) ti->private; - if (bio_barrier(bio)) - return -EOPNOTSUPP; - mpio = mempool_alloc(m->mpio_pool, GFP_NOIO); dm_bio_record(&mpio->details, bio); --- linux-source-2.6.22-2.6.22.orig/drivers/md/raid10.c +++ linux-source-2.6.22-2.6.22/drivers/md/raid10.c @@ -917,6 +917,13 @@ bio_list_add(&bl, mbio); } + if (unlikely(!atomic_read(&r10_bio->remaining))) { + /* the array is dead */ + md_write_end(mddev); + raid_end_bio_io(r10_bio); + return 0; + } + bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0); spin_lock_irqsave(&conf->device_lock, flags); bio_list_merge(&conf->pending_bio_list, &bl); @@ -1558,7 +1565,6 @@ bio = r10_bio->devs[r10_bio->read_slot].bio; r10_bio->devs[r10_bio->read_slot].bio = mddev->ro ? IO_BLOCKED : NULL; - bio_put(bio); mirror = read_balance(conf, r10_bio); if (mirror == -1) { printk(KERN_ALERT "raid10: %s: unrecoverable I/O" @@ -1566,8 +1572,10 @@ bdevname(bio->bi_bdev,b), (unsigned long long)r10_bio->sector); raid_end_bio_io(r10_bio); + bio_put(bio); } else { const int do_sync = bio_sync(r10_bio->master_bio); + bio_put(bio); rdev = conf->mirrors[mirror].rdev; if (printk_ratelimit()) printk(KERN_ERR "raid10: %s: redirecting sector %llu to" --- linux-source-2.6.22-2.6.22.orig/drivers/md/dm-io.c +++ linux-source-2.6.22-2.6.22/drivers/md/dm-io.c @@ -293,7 +293,10 @@ * bvec for bio_get/set_region() and decrement bi_max_vecs * to hide it from bio_add_page(). */ - num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2; + num_bvecs = dm_sector_div_up(remaining, + (PAGE_SIZE >> SECTOR_SHIFT)); + num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev), + num_bvecs); bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio->bi_sector = where->sector + (where->count - remaining); bio->bi_bdev = where->bdev; --- linux-source-2.6.22-2.6.22.orig/drivers/scsi/scsi_scan.c +++ linux-source-2.6.22-2.6.22/drivers/scsi/scsi_scan.c @@ -121,6 +121,7 @@ "Timeout (in seconds) waiting for devices to answer INQUIRY." " Default is 5. Some non-compliant devices need more."); +/* This lock protects only this list */ static DEFINE_SPINLOCK(async_scan_lock); static LIST_HEAD(scanning_hosts); @@ -1477,14 +1478,14 @@ if (strncmp(scsi_scan_type, "none", 4) == 0) return ERR_PTR(-ENODEV); - if (!shost->async_scan) - scsi_complete_async_scans(); - starget = scsi_alloc_target(parent, channel, id); if (!starget) return ERR_PTR(-ENOMEM); mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) + scsi_complete_async_scans(); + if (scsi_host_scan_allowed(shost)) scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); mutex_unlock(&shost->scan_mutex); @@ -1597,10 +1598,10 @@ if (strncmp(scsi_scan_type, "none", 4) == 0) return; + mutex_lock(&shost->scan_mutex); if (!shost->async_scan) scsi_complete_async_scans(); - mutex_lock(&shost->scan_mutex); if (scsi_host_scan_allowed(shost)) __scsi_scan_target(parent, channel, id, lun, rescan); mutex_unlock(&shost->scan_mutex); @@ -1645,15 +1646,15 @@ "%s: <%u:%u:%u>\n", __FUNCTION__, channel, id, lun)); - if (!shost->async_scan) - scsi_complete_async_scans(); - if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) return -EINVAL; mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) + scsi_complete_async_scans(); + if (scsi_host_scan_allowed(shost)) { if (channel == SCAN_WILD_CARD) for (channel = 0; channel <= shost->max_channel; @@ -1672,7 +1673,8 @@ { struct scsi_device *sdev; shost_for_each_device(sdev, shost) { - if (scsi_sysfs_add_sdev(sdev) != 0) + if (!scsi_host_scan_allowed(shost) || + scsi_sysfs_add_sdev(sdev) != 0) scsi_destroy_sdev(sdev); } } @@ -1690,6 +1692,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) { struct async_scan_data *data; + unsigned long flags; if (strncmp(scsi_scan_type, "sync", 4) == 0) return NULL; @@ -1709,8 +1712,13 @@ goto err; init_completion(&data->prev_finished); - spin_lock(&async_scan_lock); + mutex_lock(&shost->scan_mutex); + spin_lock_irqsave(shost->host_lock, flags); shost->async_scan = 1; + spin_unlock_irqrestore(shost->host_lock, flags); + mutex_unlock(&shost->scan_mutex); + + spin_lock(&async_scan_lock); if (list_empty(&scanning_hosts)) complete(&data->prev_finished); list_add_tail(&data->list, &scanning_hosts); @@ -1734,11 +1742,15 @@ static void scsi_finish_async_scan(struct async_scan_data *data) { struct Scsi_Host *shost; + unsigned long flags; if (!data) return; shost = data->shost; + + mutex_lock(&shost->scan_mutex); + if (!shost->async_scan) { printk("%s called twice for host %d", __FUNCTION__, shost->host_no); @@ -1750,8 +1762,13 @@ scsi_sysfs_add_devices(shost); - spin_lock(&async_scan_lock); + spin_lock_irqsave(shost->host_lock, flags); shost->async_scan = 0; + spin_unlock_irqrestore(shost->host_lock, flags); + + mutex_unlock(&shost->scan_mutex); + + spin_lock(&async_scan_lock); list_del(&data->list); if (!list_empty(&scanning_hosts)) { struct async_scan_data *next = list_entry(scanning_hosts.next, --- linux-source-2.6.22-2.6.22.orig/drivers/scsi/3w-9xxx.c +++ linux-source-2.6.22-2.6.22/drivers/scsi/3w-9xxx.c @@ -4,7 +4,7 @@ Written By: Adam Radford Modifications By: Tom Couch - Copyright (C) 2004-2006 Applied Micro Circuits Corporation. + Copyright (C) 2004-2007 Applied Micro Circuits Corporation. 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 @@ -69,6 +69,7 @@ 2.26.02.008 - Free irq handler in __twa_shutdown(). Serialize reset code. Add support for 9650SE controllers. + 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. */ #include @@ -92,7 +93,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.008" +#define TW_DRIVER_VERSION "2.26.02.009" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -2063,11 +2064,14 @@ pci_set_master(pdev); - retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK); - if (retval) { - TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); - goto out_disable_device; - } + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) + || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) + || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { + TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); + retval = -ENODEV; + goto out_disable_device; + } host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); if (!host) { --- linux-source-2.6.22-2.6.22.orig/drivers/scsi/aacraid/linit.c +++ linux-source-2.6.22-2.6.22/drivers/scsi/aacraid/linit.c @@ -597,6 +597,8 @@ static int aac_cfg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return aac_do_ioctl(file->private_data, cmd, (void __user *)arg); } @@ -650,6 +652,8 @@ static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long arg) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; return aac_compat_do_ioctl((struct aac_dev *)file->private_data, cmd, arg); } #endif --- linux-source-2.6.22-2.6.22.orig/drivers/net/niu.h +++ linux-source-2.6.22-2.6.22/drivers/net/niu.h @@ -0,0 +1,3228 @@ +/* niu.h: Definitions for Neptune ethernet driver. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#ifndef _NIU_H +#define _NIU_H + +#define PIO 0x000000UL +#define FZC_PIO 0x080000UL +#define FZC_MAC 0x180000UL +#define FZC_IPP 0x280000UL +#define FFLP 0x300000UL +#define FZC_FFLP 0x380000UL +#define PIO_VADDR 0x400000UL +#define ZCP 0x500000UL +#define FZC_ZCP 0x580000UL +#define DMC 0x600000UL +#define FZC_DMC 0x680000UL +#define TXC 0x700000UL +#define FZC_TXC 0x780000UL +#define PIO_LDSV 0x800000UL +#define PIO_PIO_LDGIM 0x900000UL +#define PIO_IMASK0 0xa00000UL +#define PIO_IMASK1 0xb00000UL +#define FZC_PROM 0xc80000UL +#define FZC_PIM 0xd80000UL + +#define LDSV0(LDG) (PIO_LDSV + 0x00000UL + (LDG) * 0x2000UL) +#define LDSV1(LDG) (PIO_LDSV + 0x00008UL + (LDG) * 0x2000UL) +#define LDSV2(LDG) (PIO_LDSV + 0x00010UL + (LDG) * 0x2000UL) + +#define LDG_IMGMT(LDG) (PIO_LDSV + 0x00018UL + (LDG) * 0x2000UL) +#define LDG_IMGMT_ARM 0x0000000080000000ULL +#define LDG_IMGMT_TIMER 0x000000000000003fULL + +#define LD_IM0(IDX) (PIO_IMASK0 + 0x00000UL + (IDX) * 0x2000UL) +#define LD_IM0_MASK 0x0000000000000003ULL + +#define LD_IM1(IDX) (PIO_IMASK1 + 0x00000UL + (IDX) * 0x2000UL) +#define LD_IM1_MASK 0x0000000000000003ULL + +#define LDG_TIMER_RES (FZC_PIO + 0x00008UL) +#define LDG_TIMER_RES_VAL 0x00000000000fffffULL + +#define DIRTY_TID_CTL (FZC_PIO + 0x00010UL) +#define DIRTY_TID_CTL_NPTHRED 0x00000000003f0000ULL +#define DIRTY_TID_CTL_RDTHRED 0x00000000000003f0ULL +#define DIRTY_TID_CTL_DTIDCLR 0x0000000000000002ULL +#define DIRTY_TID_CTL_DTIDENAB 0x0000000000000001ULL + +#define DIRTY_TID_STAT (FZC_PIO + 0x00018UL) +#define DIRTY_TID_STAT_NPWSTAT 0x0000000000003f00ULL +#define DIRTY_TID_STAT_RDSTAT 0x000000000000003fULL + +#define RST_CTL (FZC_PIO + 0x00038UL) +#define RST_CTL_MAC_RST3 0x0000000000400000ULL +#define RST_CTL_MAC_RST2 0x0000000000200000ULL +#define RST_CTL_MAC_RST1 0x0000000000100000ULL +#define RST_CTL_MAC_RST0 0x0000000000080000ULL +#define RST_CTL_ACK_TO_EN 0x0000000000000800ULL +#define RST_CTL_ACK_TO_VAL 0x00000000000007feULL + +#define SMX_CFIG_DAT (FZC_PIO + 0x00040UL) +#define SMX_CFIG_DAT_RAS_DET 0x0000000080000000ULL +#define SMX_CFIG_DAT_RAS_INJ 0x0000000040000000ULL +#define SMX_CFIG_DAT_XACT_TO 0x000000000fffffffULL + +#define SMX_INT_STAT (FZC_PIO + 0x00048UL) +#define SMX_INT_STAT_STAT 0x00000000ffffffffULL + +#define SMX_CTL (FZC_PIO + 0x00050UL) +#define SMX_CTL_CTL 0x00000000ffffffffULL + +#define SMX_DBG_VEC (FZC_PIO + 0x00058UL) +#define SMX_DBG_VEC_VEC 0x00000000ffffffffULL + +#define PIO_DBG_SEL (FZC_PIO + 0x00060UL) +#define PIO_DBG_SEL_SEL 0x000000000000003fULL + +#define PIO_TRAIN_VEC (FZC_PIO + 0x00068UL) +#define PIO_TRAIN_VEC_VEC 0x00000000ffffffffULL + +#define PIO_ARB_CTL (FZC_PIO + 0x00070UL) +#define PIO_ARB_CTL_CTL 0x00000000ffffffffULL + +#define PIO_ARB_DBG_VEC (FZC_PIO + 0x00078UL) +#define PIO_ARB_DBG_VEC_VEC 0x00000000ffffffffULL + +#define SYS_ERR_MASK (FZC_PIO + 0x00090UL) +#define SYS_ERR_MASK_META2 0x0000000000000400ULL +#define SYS_ERR_MASK_META1 0x0000000000000200ULL +#define SYS_ERR_MASK_PEU 0x0000000000000100ULL +#define SYS_ERR_MASK_TXC 0x0000000000000080ULL +#define SYS_ERR_MASK_RDMC 0x0000000000000040ULL +#define SYS_ERR_MASK_TDMC 0x0000000000000020ULL +#define SYS_ERR_MASK_ZCP 0x0000000000000010ULL +#define SYS_ERR_MASK_FFLP 0x0000000000000008ULL +#define SYS_ERR_MASK_IPP 0x0000000000000004ULL +#define SYS_ERR_MASK_MAC 0x0000000000000002ULL +#define SYS_ERR_MASK_SMX 0x0000000000000001ULL + +#define SYS_ERR_STAT (FZC_PIO + 0x00098UL) +#define SYS_ERR_STAT_META2 0x0000000000000400ULL +#define SYS_ERR_STAT_META1 0x0000000000000200ULL +#define SYS_ERR_STAT_PEU 0x0000000000000100ULL +#define SYS_ERR_STAT_TXC 0x0000000000000080ULL +#define SYS_ERR_STAT_RDMC 0x0000000000000040ULL +#define SYS_ERR_STAT_TDMC 0x0000000000000020ULL +#define SYS_ERR_STAT_ZCP 0x0000000000000010ULL +#define SYS_ERR_STAT_FFLP 0x0000000000000008ULL +#define SYS_ERR_STAT_IPP 0x0000000000000004ULL +#define SYS_ERR_STAT_MAC 0x0000000000000002ULL +#define SYS_ERR_STAT_SMX 0x0000000000000001ULL + +#define SID(LDG) (FZC_PIO + 0x10200UL + (LDG) * 8UL) +#define SID_FUNC 0x0000000000000060ULL +#define SID_FUNC_SHIFT 5 +#define SID_VECTOR 0x000000000000001fULL +#define SID_VECTOR_SHIFT 0 + +#define LDG_NUM(LDN) (FZC_PIO + 0x20000UL + (LDN) * 8UL) + +#define XMAC_PORT0_OFF (FZC_MAC + 0x000000) +#define XMAC_PORT1_OFF (FZC_MAC + 0x006000) +#define BMAC_PORT2_OFF (FZC_MAC + 0x00c000) +#define BMAC_PORT3_OFF (FZC_MAC + 0x010000) + +/* XMAC registers, offset from np->mac_regs */ + +#define XTXMAC_SW_RST 0x00000UL +#define XTXMAC_SW_RST_REG_RS 0x0000000000000002ULL +#define XTXMAC_SW_RST_SOFT_RST 0x0000000000000001ULL + +#define XRXMAC_SW_RST 0x00008UL +#define XRXMAC_SW_RST_REG_RS 0x0000000000000002ULL +#define XRXMAC_SW_RST_SOFT_RST 0x0000000000000001ULL + +#define XTXMAC_STATUS 0x00020UL +#define XTXMAC_STATUS_FRAME_CNT_EXP 0x0000000000000800ULL +#define XTXMAC_STATUS_BYTE_CNT_EXP 0x0000000000000400ULL +#define XTXMAC_STATUS_TXFIFO_XFR_ERR 0x0000000000000010ULL +#define XTXMAC_STATUS_TXMAC_OFLOW 0x0000000000000008ULL +#define XTXMAC_STATUS_MAX_PSIZE_ERR 0x0000000000000004ULL +#define XTXMAC_STATUS_TXMAC_UFLOW 0x0000000000000002ULL +#define XTXMAC_STATUS_FRAME_XMITED 0x0000000000000001ULL + +#define XRXMAC_STATUS 0x00028UL +#define XRXMAC_STATUS_RXHIST7_CNT_EXP 0x0000000000100000ULL +#define XRXMAC_STATUS_LCL_FLT_STATUS 0x0000000000080000ULL +#define XRXMAC_STATUS_RFLT_DET 0x0000000000040000ULL +#define XRXMAC_STATUS_LFLT_CNT_EXP 0x0000000000020000ULL +#define XRXMAC_STATUS_PHY_MDINT 0x0000000000010000ULL +#define XRXMAC_STATUS_ALIGNERR_CNT_EXP 0x0000000000010000ULL +#define XRXMAC_STATUS_RXFRAG_CNT_EXP 0x0000000000008000ULL +#define XRXMAC_STATUS_RXMULTF_CNT_EXP 0x0000000000004000ULL +#define XRXMAC_STATUS_RXBCAST_CNT_EXP 0x0000000000002000ULL +#define XRXMAC_STATUS_RXHIST6_CNT_EXP 0x0000000000001000ULL +#define XRXMAC_STATUS_RXHIST5_CNT_EXP 0x0000000000000800ULL +#define XRXMAC_STATUS_RXHIST4_CNT_EXP 0x0000000000000400ULL +#define XRXMAC_STATUS_RXHIST3_CNT_EXP 0x0000000000000200ULL +#define XRXMAC_STATUS_RXHIST2_CNT_EXP 0x0000000000000100ULL +#define XRXMAC_STATUS_RXHIST1_CNT_EXP 0x0000000000000080ULL +#define XRXMAC_STATUS_RXOCTET_CNT_EXP 0x0000000000000040ULL +#define XRXMAC_STATUS_CVIOLERR_CNT_EXP 0x0000000000000020ULL +#define XRXMAC_STATUS_LENERR_CNT_EXP 0x0000000000000010ULL +#define XRXMAC_STATUS_CRCERR_CNT_EXP 0x0000000000000008ULL +#define XRXMAC_STATUS_RXUFLOW 0x0000000000000004ULL +#define XRXMAC_STATUS_RXOFLOW 0x0000000000000002ULL +#define XRXMAC_STATUS_FRAME_RCVD 0x0000000000000001ULL + +#define XMAC_FC_STAT 0x00030UL +#define XMAC_FC_STAT_RX_RCV_PAUSE_TIME 0x00000000ffff0000ULL +#define XMAC_FC_STAT_TX_MAC_NPAUSE 0x0000000000000004ULL +#define XMAC_FC_STAT_TX_MAC_PAUSE 0x0000000000000002ULL +#define XMAC_FC_STAT_RX_MAC_RPAUSE 0x0000000000000001ULL + +#define XTXMAC_STAT_MSK 0x00040UL +#define XTXMAC_STAT_MSK_FRAME_CNT_EXP 0x0000000000000800ULL +#define XTXMAC_STAT_MSK_BYTE_CNT_EXP 0x0000000000000400ULL +#define XTXMAC_STAT_MSK_TXFIFO_XFR_ERR 0x0000000000000010ULL +#define XTXMAC_STAT_MSK_TXMAC_OFLOW 0x0000000000000008ULL +#define XTXMAC_STAT_MSK_MAX_PSIZE_ERR 0x0000000000000004ULL +#define XTXMAC_STAT_MSK_TXMAC_UFLOW 0x0000000000000002ULL +#define XTXMAC_STAT_MSK_FRAME_XMITED 0x0000000000000001ULL + +#define XRXMAC_STAT_MSK 0x00048UL +#define XRXMAC_STAT_MSK_LCL_FLT_STAT_MSK 0x0000000000080000ULL +#define XRXMAC_STAT_MSK_RFLT_DET 0x0000000000040000ULL +#define XRXMAC_STAT_MSK_LFLT_CNT_EXP 0x0000000000020000ULL +#define XRXMAC_STAT_MSK_PHY_MDINT 0x0000000000010000ULL +#define XRXMAC_STAT_MSK_RXFRAG_CNT_EXP 0x0000000000008000ULL +#define XRXMAC_STAT_MSK_RXMULTF_CNT_EXP 0x0000000000004000ULL +#define XRXMAC_STAT_MSK_RXBCAST_CNT_EXP 0x0000000000002000ULL +#define XRXMAC_STAT_MSK_RXHIST6_CNT_EXP 0x0000000000001000ULL +#define XRXMAC_STAT_MSK_RXHIST5_CNT_EXP 0x0000000000000800ULL +#define XRXMAC_STAT_MSK_RXHIST4_CNT_EXP 0x0000000000000400ULL +#define XRXMAC_STAT_MSK_RXHIST3_CNT_EXP 0x0000000000000200ULL +#define XRXMAC_STAT_MSK_RXHIST2_CNT_EXP 0x0000000000000100ULL +#define XRXMAC_STAT_MSK_RXHIST1_CNT_EXP 0x0000000000000080ULL +#define XRXMAC_STAT_MSK_RXOCTET_CNT_EXP 0x0000000000000040ULL +#define XRXMAC_STAT_MSK_CVIOLERR_CNT_EXP 0x0000000000000020ULL +#define XRXMAC_STAT_MSK_LENERR_CNT_EXP 0x0000000000000010ULL +#define XRXMAC_STAT_MSK_CRCERR_CNT_EXP 0x0000000000000008ULL +#define XRXMAC_STAT_MSK_RXUFLOW_CNT_EXP 0x0000000000000004ULL +#define XRXMAC_STAT_MSK_RXOFLOW_CNT_EXP 0x0000000000000002ULL +#define XRXMAC_STAT_MSK_FRAME_RCVD 0x0000000000000001ULL + +#define XMAC_FC_MSK 0x00050UL +#define XMAC_FC_MSK_TX_MAC_NPAUSE 0x0000000000000004ULL +#define XMAC_FC_MSK_TX_MAC_PAUSE 0x0000000000000002ULL +#define XMAC_FC_MSK_RX_MAC_RPAUSE 0x0000000000000001ULL + +#define XMAC_CONFIG 0x00060UL +#define XMAC_CONFIG_SEL_CLK_25MHZ 0x0000000080000000ULL +#define XMAC_CONFIG_1G_PCS_BYPASS 0x0000000040000000ULL +#define XMAC_CONFIG_10G_XPCS_BYPASS 0x0000000020000000ULL +#define XMAC_CONFIG_MODE_MASK 0x0000000018000000ULL +#define XMAC_CONFIG_MODE_XGMII 0x0000000000000000ULL +#define XMAC_CONFIG_MODE_GMII 0x0000000008000000ULL +#define XMAC_CONFIG_MODE_MII 0x0000000010000000ULL +#define XMAC_CONFIG_LFS_DISABLE 0x0000000004000000ULL +#define XMAC_CONFIG_LOOPBACK 0x0000000002000000ULL +#define XMAC_CONFIG_TX_OUTPUT_EN 0x0000000001000000ULL +#define XMAC_CONFIG_SEL_POR_CLK_SRC 0x0000000000800000ULL +#define XMAC_CONFIG_LED_POLARITY 0x0000000000400000ULL +#define XMAC_CONFIG_FORCE_LED_ON 0x0000000000200000ULL +#define XMAC_CONFIG_PASS_FLOW_CTRL 0x0000000000100000ULL +#define XMAC_CONFIG_RCV_PAUSE_ENABLE 0x0000000000080000ULL +#define XMAC_CONFIG_MAC2IPP_PKT_CNT_EN 0x0000000000040000ULL +#define XMAC_CONFIG_STRIP_CRC 0x0000000000020000ULL +#define XMAC_CONFIG_ADDR_FILTER_EN 0x0000000000010000ULL +#define XMAC_CONFIG_HASH_FILTER_EN 0x0000000000008000ULL +#define XMAC_CONFIG_RX_CODEV_CHK_DIS 0x0000000000004000ULL +#define XMAC_CONFIG_RESERVED_MULTICAST 0x0000000000002000ULL +#define XMAC_CONFIG_RX_CRC_CHK_DIS 0x0000000000001000ULL +#define XMAC_CONFIG_ERR_CHK_DIS 0x0000000000000800ULL +#define XMAC_CONFIG_PROMISC_GROUP 0x0000000000000400ULL +#define XMAC_CONFIG_PROMISCUOUS 0x0000000000000200ULL +#define XMAC_CONFIG_RX_MAC_ENABLE 0x0000000000000100ULL +#define XMAC_CONFIG_WARNING_MSG_EN 0x0000000000000080ULL +#define XMAC_CONFIG_ALWAYS_NO_CRC 0x0000000000000008ULL +#define XMAC_CONFIG_VAR_MIN_IPG_EN 0x0000000000000004ULL +#define XMAC_CONFIG_STRETCH_MODE 0x0000000000000002ULL +#define XMAC_CONFIG_TX_ENABLE 0x0000000000000001ULL + +#define XMAC_IPG 0x00080UL +#define XMAC_IPG_STRETCH_CONST 0x0000000000e00000ULL +#define XMAC_IPG_STRETCH_CONST_SHIFT 21 +#define XMAC_IPG_STRETCH_RATIO 0x00000000001f0000ULL +#define XMAC_IPG_STRETCH_RATIO_SHIFT 16 +#define XMAC_IPG_IPG_MII_GMII 0x000000000000ff00ULL +#define XMAC_IPG_IPG_MII_GMII_SHIFT 8 +#define XMAC_IPG_IPG_XGMII 0x0000000000000007ULL +#define XMAC_IPG_IPG_XGMII_SHIFT 0 + +#define IPG_12_15_XGMII 3 +#define IPG_16_19_XGMII 4 +#define IPG_20_23_XGMII 5 +#define IPG_12_MII_GMII 10 +#define IPG_13_MII_GMII 11 +#define IPG_14_MII_GMII 12 +#define IPG_15_MII_GMII 13 +#define IPG_16_MII_GMII 14 + +#define XMAC_MIN 0x00088UL +#define XMAC_MIN_RX_MIN_PKT_SIZE 0x000000003ff00000ULL +#define XMAC_MIN_RX_MIN_PKT_SIZE_SHFT 20 +#define XMAC_MIN_SLOT_TIME 0x000000000003fc00ULL +#define XMAC_MIN_SLOT_TIME_SHFT 10 +#define XMAC_MIN_TX_MIN_PKT_SIZE 0x00000000000003ffULL +#define XMAC_MIN_TX_MIN_PKT_SIZE_SHFT 0 + +#define XMAC_MAX 0x00090UL +#define XMAC_MAX_FRAME_SIZE 0x0000000000003fffULL +#define XMAC_MAX_FRAME_SIZE_SHFT 0 + +#define XMAC_ADDR0 0x000a0UL +#define XMAC_ADDR0_ADDR0 0x000000000000ffffULL + +#define XMAC_ADDR1 0x000a8UL +#define XMAC_ADDR1_ADDR1 0x000000000000ffffULL + +#define XMAC_ADDR2 0x000b0UL +#define XMAC_ADDR2_ADDR2 0x000000000000ffffULL + +#define XMAC_ADDR_CMPEN 0x00208UL +#define XMAC_ADDR_CMPEN_EN15 0x0000000000008000ULL +#define XMAC_ADDR_CMPEN_EN14 0x0000000000004000ULL +#define XMAC_ADDR_CMPEN_EN13 0x0000000000002000ULL +#define XMAC_ADDR_CMPEN_EN12 0x0000000000001000ULL +#define XMAC_ADDR_CMPEN_EN11 0x0000000000000800ULL +#define XMAC_ADDR_CMPEN_EN10 0x0000000000000400ULL +#define XMAC_ADDR_CMPEN_EN9 0x0000000000000200ULL +#define XMAC_ADDR_CMPEN_EN8 0x0000000000000100ULL +#define XMAC_ADDR_CMPEN_EN7 0x0000000000000080ULL +#define XMAC_ADDR_CMPEN_EN6 0x0000000000000040ULL +#define XMAC_ADDR_CMPEN_EN5 0x0000000000000020ULL +#define XMAC_ADDR_CMPEN_EN4 0x0000000000000010ULL +#define XMAC_ADDR_CMPEN_EN3 0x0000000000000008ULL +#define XMAC_ADDR_CMPEN_EN2 0x0000000000000004ULL +#define XMAC_ADDR_CMPEN_EN1 0x0000000000000002ULL +#define XMAC_ADDR_CMPEN_EN0 0x0000000000000001ULL + +#define XMAC_NUM_ALT_ADDR 16 + +#define XMAC_ALT_ADDR0(NUM) (0x00218UL + (NUM)*0x18UL) +#define XMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL + +#define XMAC_ALT_ADDR1(NUM) (0x00220UL + (NUM)*0x18UL) +#define XMAC_ALT_ADDR1_ADDR1 0x000000000000ffffULL + +#define XMAC_ALT_ADDR2(NUM) (0x00228UL + (NUM)*0x18UL) +#define XMAC_ALT_ADDR2_ADDR2 0x000000000000ffffULL + +#define XMAC_ADD_FILT0 0x00818UL +#define XMAC_ADD_FILT0_FILT0 0x000000000000ffffULL + +#define XMAC_ADD_FILT1 0x00820UL +#define XMAC_ADD_FILT1_FILT1 0x000000000000ffffULL + +#define XMAC_ADD_FILT2 0x00828UL +#define XMAC_ADD_FILT2_FILT2 0x000000000000ffffULL + +#define XMAC_ADD_FILT12_MASK 0x00830UL +#define XMAC_ADD_FILT12_MASK_VAL 0x00000000000000ffULL + +#define XMAC_ADD_FILT00_MASK 0x00838UL +#define XMAC_ADD_FILT00_MASK_VAL 0x000000000000ffffULL + +#define XMAC_HASH_TBL(NUM) (0x00840UL + (NUM) * 0x8UL) +#define XMAC_HASH_TBL_VAL 0x000000000000ffffULL + +#define XMAC_NUM_HOST_INFO 20 + +#define XMAC_HOST_INFO(NUM) (0x00900UL + (NUM) * 0x8UL) + +#define XMAC_PA_DATA0 0x00b80UL +#define XMAC_PA_DATA0_VAL 0x00000000ffffffffULL + +#define XMAC_PA_DATA1 0x00b88UL +#define XMAC_PA_DATA1_VAL 0x00000000ffffffffULL + +#define XMAC_DEBUG_SEL 0x00b90UL +#define XMAC_DEBUG_SEL_XMAC 0x0000000000000078ULL +#define XMAC_DEBUG_SEL_MAC 0x0000000000000007ULL + +#define XMAC_TRAIN_VEC 0x00b98UL +#define XMAC_TRAIN_VEC_VAL 0x00000000ffffffffULL + +#define RXMAC_BT_CNT 0x00100UL +#define RXMAC_BT_CNT_COUNT 0x00000000ffffffffULL + +#define RXMAC_BC_FRM_CNT 0x00108UL +#define RXMAC_BC_FRM_CNT_COUNT 0x00000000001fffffULL + +#define RXMAC_MC_FRM_CNT 0x00110UL +#define RXMAC_MC_FRM_CNT_COUNT 0x00000000001fffffULL + +#define RXMAC_FRAG_CNT 0x00118UL +#define RXMAC_FRAG_CNT_COUNT 0x00000000001fffffULL + +#define RXMAC_HIST_CNT1 0x00120UL +#define RXMAC_HIST_CNT1_COUNT 0x00000000001fffffULL + +#define RXMAC_HIST_CNT2 0x00128UL +#define RXMAC_HIST_CNT2_COUNT 0x00000000001fffffULL + +#define RXMAC_HIST_CNT3 0x00130UL +#define RXMAC_HIST_CNT3_COUNT 0x00000000000fffffULL + +#define RXMAC_HIST_CNT4 0x00138UL +#define RXMAC_HIST_CNT4_COUNT 0x000000000007ffffULL + +#define RXMAC_HIST_CNT5 0x00140UL +#define RXMAC_HIST_CNT5_COUNT 0x000000000003ffffULL + +#define RXMAC_HIST_CNT6 0x00148UL +#define RXMAC_HIST_CNT6_COUNT 0x000000000000ffffULL + +#define RXMAC_MPSZER_CNT 0x00150UL +#define RXMAC_MPSZER_CNT_COUNT 0x00000000000000ffULL + +#define RXMAC_CRC_ER_CNT 0x00158UL +#define RXMAC_CRC_ER_CNT_COUNT 0x00000000000000ffULL + +#define RXMAC_CD_VIO_CNT 0x00160UL +#define RXMAC_CD_VIO_CNT_COUNT 0x00000000000000ffULL + +#define RXMAC_ALIGN_ERR_CNT 0x00168UL +#define RXMAC_ALIGN_ERR_CNT_COUNT 0x00000000000000ffULL + +#define TXMAC_FRM_CNT 0x00170UL +#define TXMAC_FRM_CNT_COUNT 0x00000000ffffffffULL + +#define TXMAC_BYTE_CNT 0x00178UL +#define TXMAC_BYTE_CNT_COUNT 0x00000000ffffffffULL + +#define LINK_FAULT_CNT 0x00180UL +#define LINK_FAULT_CNT_COUNT 0x00000000000000ffULL + +#define RXMAC_HIST_CNT7 0x00188UL +#define RXMAC_HIST_CNT7_COUNT 0x0000000007ffffffULL + +#define XMAC_SM_REG 0x001a8UL +#define XMAC_SM_REG_STATE 0x00000000ffffffffULL + +#define XMAC_INTER1 0x001b0UL +#define XMAC_INTERN1_SIGNALS1 0x00000000ffffffffULL + +#define XMAC_INTER2 0x001b8UL +#define XMAC_INTERN2_SIGNALS2 0x00000000ffffffffULL + +/* BMAC registers, offset from np->mac_regs */ + +#define BTXMAC_SW_RST 0x00000UL +#define BTXMAC_SW_RST_RESET 0x0000000000000001ULL + +#define BRXMAC_SW_RST 0x00008UL +#define BRXMAC_SW_RST_RESET 0x0000000000000001ULL + +#define BMAC_SEND_PAUSE 0x00010UL +#define BMAC_SEND_PAUSE_SEND 0x0000000000010000ULL +#define BMAC_SEND_PAUSE_TIME 0x000000000000ffffULL + +#define BTXMAC_STATUS 0x00020UL +#define BTXMAC_STATUS_XMIT 0x0000000000000001ULL +#define BTXMAC_STATUS_UNDERRUN 0x0000000000000002ULL +#define BTXMAC_STATUS_MAX_PKT_ERR 0x0000000000000004ULL +#define BTXMAC_STATUS_BYTE_CNT_EXP 0x0000000000000400ULL +#define BTXMAC_STATUS_FRAME_CNT_EXP 0x0000000000000800ULL + +#define BRXMAC_STATUS 0x00028UL +#define BRXMAC_STATUS_RX_PKT 0x0000000000000001ULL +#define BRXMAC_STATUS_OVERFLOW 0x0000000000000002ULL +#define BRXMAC_STATUS_FRAME_CNT_EXP 0x0000000000000004ULL +#define BRXMAC_STATUS_ALIGN_ERR_EXP 0x0000000000000008ULL +#define BRXMAC_STATUS_CRC_ERR_EXP 0x0000000000000010ULL +#define BRXMAC_STATUS_LEN_ERR_EXP 0x0000000000000020ULL + +#define BMAC_CTRL_STATUS 0x00030UL +#define BMAC_CTRL_STATUS_PAUSE_RECV 0x0000000000000001ULL +#define BMAC_CTRL_STATUS_PAUSE 0x0000000000000002ULL +#define BMAC_CTRL_STATUS_NOPAUSE 0x0000000000000004ULL +#define BMAC_CTRL_STATUS_TIME 0x00000000ffff0000ULL +#define BMAC_CTRL_STATUS_TIME_SHIFT 16 + +#define BTXMAC_STATUS_MASK 0x00040UL +#define BRXMAC_STATUS_MASK 0x00048UL +#define BMAC_CTRL_STATUS_MASK 0x00050UL + +#define BTXMAC_CONFIG 0x00060UL +#define BTXMAC_CONFIG_ENABLE 0x0000000000000001ULL +#define BTXMAC_CONFIG_FCS_DISABLE 0x0000000000000002ULL + +#define BRXMAC_CONFIG 0x00068UL +#define BRXMAC_CONFIG_DISCARD_DIS 0x0000000000000080ULL +#define BRXMAC_CONFIG_ADDR_FILT_EN 0x0000000000000040ULL +#define BRXMAC_CONFIG_HASH_FILT_EN 0x0000000000000020ULL +#define BRXMAC_CONFIG_PROMISC_GRP 0x0000000000000010ULL +#define BRXMAC_CONFIG_PROMISC 0x0000000000000008ULL +#define BRXMAC_CONFIG_STRIP_FCS 0x0000000000000004ULL +#define BRXMAC_CONFIG_STRIP_PAD 0x0000000000000002ULL +#define BRXMAC_CONFIG_ENABLE 0x0000000000000001ULL + +#define BMAC_CTRL_CONFIG 0x00070UL +#define BMAC_CTRL_CONFIG_TX_PAUSE_EN 0x0000000000000001ULL +#define BMAC_CTRL_CONFIG_RX_PAUSE_EN 0x0000000000000002ULL +#define BMAC_CTRL_CONFIG_PASS_CTRL 0x0000000000000004ULL + +#define BMAC_XIF_CONFIG 0x00078UL +#define BMAC_XIF_CONFIG_TX_OUTPUT_EN 0x0000000000000001ULL +#define BMAC_XIF_CONFIG_MII_LOOPBACK 0x0000000000000002ULL +#define BMAC_XIF_CONFIG_GMII_MODE 0x0000000000000008ULL +#define BMAC_XIF_CONFIG_LINK_LED 0x0000000000000020ULL +#define BMAC_XIF_CONFIG_LED_POLARITY 0x0000000000000040ULL +#define BMAC_XIF_CONFIG_25MHZ_CLOCK 0x0000000000000080ULL + +#define BMAC_MIN_FRAME 0x000a0UL +#define BMAC_MIN_FRAME_VAL 0x00000000000003ffULL + +#define BMAC_MAX_FRAME 0x000a8UL +#define BMAC_MAX_FRAME_MAX_BURST 0x000000003fff0000ULL +#define BMAC_MAX_FRAME_MAX_BURST_SHIFT 16 +#define BMAC_MAX_FRAME_MAX_FRAME 0x0000000000003fffULL +#define BMAC_MAX_FRAME_MAX_FRAME_SHIFT 0 + +#define BMAC_PREAMBLE_SIZE 0x000b0UL +#define BMAC_PREAMBLE_SIZE_VAL 0x00000000000003ffULL + +#define BMAC_CTRL_TYPE 0x000c8UL + +#define BMAC_ADDR0 0x00100UL +#define BMAC_ADDR0_ADDR0 0x000000000000ffffULL + +#define BMAC_ADDR1 0x00108UL +#define BMAC_ADDR1_ADDR1 0x000000000000ffffULL + +#define BMAC_ADDR2 0x00110UL +#define BMAC_ADDR2_ADDR2 0x000000000000ffffULL + +#define BMAC_NUM_ALT_ADDR 7 + +#define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL) +#define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL + +#define BMAC_ALT_ADDR1(NUM) (0x00120UL + (NUM)*0x18UL) +#define BMAC_ALT_ADDR1_ADDR1 0x000000000000ffffULL + +#define BMAC_ALT_ADDR2(NUM) (0x00128UL + (NUM)*0x18UL) +#define BMAC_ALT_ADDR2_ADDR2 0x000000000000ffffULL + +#define BMAC_FC_ADDR0 0x00268UL +#define BMAC_FC_ADDR0_ADDR0 0x000000000000ffffULL + +#define BMAC_FC_ADDR1 0x00270UL +#define BMAC_FC_ADDR1_ADDR1 0x000000000000ffffULL + +#define BMAC_FC_ADDR2 0x00278UL +#define BMAC_FC_ADDR2_ADDR2 0x000000000000ffffULL + +#define BMAC_ADD_FILT0 0x00298UL +#define BMAC_ADD_FILT0_FILT0 0x000000000000ffffULL + +#define BMAC_ADD_FILT1 0x002a0UL +#define BMAC_ADD_FILT1_FILT1 0x000000000000ffffULL + +#define BMAC_ADD_FILT2 0x002a8UL +#define BMAC_ADD_FILT2_FILT2 0x000000000000ffffULL + +#define BMAC_ADD_FILT12_MASK 0x002b0UL +#define BMAC_ADD_FILT12_MASK_VAL 0x00000000000000ffULL + +#define BMAC_ADD_FILT00_MASK 0x002b8UL +#define BMAC_ADD_FILT00_MASK_VAL 0x000000000000ffffULL + +#define BMAC_HASH_TBL(NUM) (0x002c0UL + (NUM) * 0x8UL) +#define BMAC_HASH_TBL_VAL 0x000000000000ffffULL + +#define BRXMAC_FRAME_CNT 0x00370 +#define BRXMAC_FRAME_CNT_COUNT 0x000000000000ffffULL + +#define BRXMAC_MAX_LEN_ERR_CNT 0x00378 + +#define BRXMAC_ALIGN_ERR_CNT 0x00380 +#define BRXMAC_ALIGN_ERR_CNT_COUNT 0x000000000000ffffULL + +#define BRXMAC_CRC_ERR_CNT 0x00388 +#define BRXMAC_ALIGN_ERR_CNT_COUNT 0x000000000000ffffULL + +#define BRXMAC_CODE_VIOL_ERR_CNT 0x00390 +#define BRXMAC_CODE_VIOL_ERR_CNT_COUNT 0x000000000000ffffULL + +#define BMAC_STATE_MACHINE 0x003a0 + +#define BMAC_ADDR_CMPEN 0x003f8UL +#define BMAC_ADDR_CMPEN_EN15 0x0000000000008000ULL +#define BMAC_ADDR_CMPEN_EN14 0x0000000000004000ULL +#define BMAC_ADDR_CMPEN_EN13 0x0000000000002000ULL +#define BMAC_ADDR_CMPEN_EN12 0x0000000000001000ULL +#define BMAC_ADDR_CMPEN_EN11 0x0000000000000800ULL +#define BMAC_ADDR_CMPEN_EN10 0x0000000000000400ULL +#define BMAC_ADDR_CMPEN_EN9 0x0000000000000200ULL +#define BMAC_ADDR_CMPEN_EN8 0x0000000000000100ULL +#define BMAC_ADDR_CMPEN_EN7 0x0000000000000080ULL +#define BMAC_ADDR_CMPEN_EN6 0x0000000000000040ULL +#define BMAC_ADDR_CMPEN_EN5 0x0000000000000020ULL +#define BMAC_ADDR_CMPEN_EN4 0x0000000000000010ULL +#define BMAC_ADDR_CMPEN_EN3 0x0000000000000008ULL +#define BMAC_ADDR_CMPEN_EN2 0x0000000000000004ULL +#define BMAC_ADDR_CMPEN_EN1 0x0000000000000002ULL +#define BMAC_ADDR_CMPEN_EN0 0x0000000000000001ULL + +#define BMAC_NUM_HOST_INFO 9 + +#define BMAC_HOST_INFO(NUM) (0x00400UL + (NUM) * 0x8UL) + +#define BTXMAC_BYTE_CNT 0x00448UL +#define BTXMAC_BYTE_CNT_COUNT 0x00000000ffffffffULL + +#define BTXMAC_FRM_CNT 0x00450UL +#define BTXMAC_FRM_CNT_COUNT 0x00000000ffffffffULL + +#define BRXMAC_BYTE_CNT 0x00458UL +#define BRXMAC_BYTE_CNT_COUNT 0x00000000ffffffffULL + +#define HOST_INFO_MPR 0x0000000000000100ULL +#define HOST_INFO_MACRDCTBLN 0x0000000000000007ULL + +/* XPCS registers, offset from np->regs + np->xpcs_off */ + +#define XPCS_CONTROL1 (FZC_MAC + 0x00000UL) +#define XPCS_CONTROL1_RESET 0x0000000000008000ULL +#define XPCS_CONTROL1_LOOPBACK 0x0000000000004000ULL +#define XPCS_CONTROL1_SPEED_SELECT3 0x0000000000002000ULL +#define XPCS_CONTROL1_CSR_LOW_PWR 0x0000000000000800ULL +#define XPCS_CONTROL1_CSR_SPEED1 0x0000000000000040ULL +#define XPCS_CONTROL1_CSR_SPEED0 0x000000000000003cULL + +#define XPCS_STATUS1 (FZC_MAC + 0x00008UL) +#define XPCS_STATUS1_CSR_FAULT 0x0000000000000080ULL +#define XPCS_STATUS1_CSR_RXLNK_STAT 0x0000000000000004ULL +#define XPCS_STATUS1_CSR_LPWR_ABLE 0x0000000000000002ULL + +#define XPCS_DEVICE_IDENTIFIER (FZC_MAC + 0x00010UL) +#define XPCS_DEVICE_IDENTIFIER_VAL 0x00000000ffffffffULL + +#define XPCS_SPEED_ABILITY (FZC_MAC + 0x00018UL) +#define XPCS_SPEED_ABILITY_10GIG 0x0000000000000001ULL + +#define XPCS_DEV_IN_PKG (FZC_MAC + 0x00020UL) +#define XPCS_DEV_IN_PKG_CSR_VEND2 0x0000000080000000ULL +#define XPCS_DEV_IN_PKG_CSR_VEND1 0x0000000040000000ULL +#define XPCS_DEV_IN_PKG_DTE_XS 0x0000000000000020ULL +#define XPCS_DEV_IN_PKG_PHY_XS 0x0000000000000010ULL +#define XPCS_DEV_IN_PKG_PCS 0x0000000000000008ULL +#define XPCS_DEV_IN_PKG_WIS 0x0000000000000004ULL +#define XPCS_DEV_IN_PKG_PMD_PMA 0x0000000000000002ULL +#define XPCS_DEV_IN_PKG_CLS22 0x0000000000000001ULL + +#define XPCS_CONTROL2 (FZC_MAC + 0x00028UL) +#define XPCS_CONTROL2_CSR_PSC_SEL 0x0000000000000003ULL + +#define XPCS_STATUS2 (FZC_MAC + 0x00030UL) +#define XPCS_STATUS2_CSR_DEV_PRES 0x000000000000c000ULL +#define XPCS_STATUS2_CSR_TX_FAULT 0x0000000000000800ULL +#define XPCS_STATUS2_CSR_RCV_FAULT 0x0000000000000400ULL +#define XPCS_STATUS2_TEN_GBASE_W 0x0000000000000004ULL +#define XPCS_STATUS2_TEN_GBASE_X 0x0000000000000002ULL +#define XPCS_STATUS2_TEN_GBASE_R 0x0000000000000001ULL + +#define XPCS_PKG_ID (FZC_MAC + 0x00038UL) +#define XPCS_PKG_ID_VAL 0x00000000ffffffffULL + +#define XPCS_STATUS(IDX) (FZC_MAC + 0x00040UL) +#define XPCS_STATUS_CSR_LANE_ALIGN 0x0000000000001000ULL +#define XPCS_STATUS_CSR_PATTEST_CAP 0x0000000000000800ULL +#define XPCS_STATUS_CSR_LANE3_SYNC 0x0000000000000008ULL +#define XPCS_STATUS_CSR_LANE2_SYNC 0x0000000000000004ULL +#define XPCS_STATUS_CSR_LANE1_SYNC 0x0000000000000002ULL +#define XPCS_STATUS_CSR_LANE0_SYNC 0x0000000000000001ULL + +#define XPCS_TEST_CONTROL (FZC_MAC + 0x00048UL) +#define XPCS_TEST_CONTROL_TXTST_EN 0x0000000000000004ULL +#define XPCS_TEST_CONTROL_TPAT_SEL 0x0000000000000003ULL + +#define XPCS_CFG_VENDOR1 (FZC_MAC + 0x00050UL) +#define XPCS_CFG_VENDOR1_DBG_IOTST 0x0000000000000080ULL +#define XPCS_CFG_VENDOR1_DBG_SEL 0x0000000000000078ULL +#define XPCS_CFG_VENDOR1_BYPASS_DET 0x0000000000000004ULL +#define XPCS_CFG_VENDOR1_TXBUF_EN 0x0000000000000002ULL +#define XPCS_CFG_VENDOR1_XPCS_EN 0x0000000000000001ULL + +#define XPCS_DIAG_VENDOR2 (FZC_MAC + 0x00058UL) +#define XPCS_DIAG_VENDOR2_SSM_LANE3 0x0000000001e00000ULL +#define XPCS_DIAG_VENDOR2_SSM_LANE2 0x00000000001e0000ULL +#define XPCS_DIAG_VENDOR2_SSM_LANE1 0x000000000001e000ULL +#define XPCS_DIAG_VENDOR2_SSM_LANE0 0x0000000000001e00ULL +#define XPCS_DIAG_VENDOR2_EBUF_SM 0x00000000000001feULL +#define XPCS_DIAG_VENDOR2_RCV_SM 0x0000000000000001ULL + +#define XPCS_MASK1 (FZC_MAC + 0x00060UL) +#define XPCS_MASK1_FAULT_MASK 0x0000000000000080ULL +#define XPCS_MASK1_RXALIGN_STAT_MSK 0x0000000000000004ULL + +#define XPCS_PKT_COUNT (FZC_MAC + 0x00068UL) +#define XPCS_PKT_COUNT_TX 0x00000000ffff0000ULL +#define XPCS_PKT_COUNT_RX 0x000000000000ffffULL + +#define XPCS_TX_SM (FZC_MAC + 0x00070UL) +#define XPCS_TX_SM_VAL 0x000000000000000fULL + +#define XPCS_DESKEW_ERR_CNT (FZC_MAC + 0x00078UL) +#define XPCS_DESKEW_ERR_CNT_VAL 0x00000000000000ffULL + +#define XPCS_SYMERR_CNT01 (FZC_MAC + 0x00080UL) +#define XPCS_SYMERR_CNT01_LANE1 0x00000000ffff0000ULL +#define XPCS_SYMERR_CNT01_LANE0 0x000000000000ffffULL + +#define XPCS_SYMERR_CNT23 (FZC_MAC + 0x00088UL) +#define XPCS_SYMERR_CNT23_LANE3 0x00000000ffff0000ULL +#define XPCS_SYMERR_CNT23_LANE2 0x000000000000ffffULL + +#define XPCS_TRAINING_VECTOR (FZC_MAC + 0x00090UL) +#define XPCS_TRAINING_VECTOR_VAL 0x00000000ffffffffULL + +/* PCS registers, offset from np->regs + np->pcs_off */ + +#define PCS_MII_CTL (FZC_MAC + 0x00000UL) +#define PCS_MII_CTL_RST 0x0000000000008000ULL +#define PCS_MII_CTL_10_100_SPEED 0x0000000000002000ULL +#define PCS_MII_AUTONEG_EN 0x0000000000001000ULL +#define PCS_MII_PWR_DOWN 0x0000000000000800ULL +#define PCS_MII_ISOLATE 0x0000000000000400ULL +#define PCS_MII_AUTONEG_RESTART 0x0000000000000200ULL +#define PCS_MII_DUPLEX 0x0000000000000100ULL +#define PCS_MII_COLL_TEST 0x0000000000000080ULL +#define PCS_MII_1000MB_SPEED 0x0000000000000040ULL + +#define PCS_MII_STAT (FZC_MAC + 0x00008UL) +#define PCS_MII_STAT_EXT_STATUS 0x0000000000000100ULL +#define PCS_MII_STAT_AUTONEG_DONE 0x0000000000000020ULL +#define PCS_MII_STAT_REMOTE_FAULT 0x0000000000000010ULL +#define PCS_MII_STAT_AUTONEG_ABLE 0x0000000000000008ULL +#define PCS_MII_STAT_LINK_STATUS 0x0000000000000004ULL +#define PCS_MII_STAT_JABBER_DET 0x0000000000000002ULL +#define PCS_MII_STAT_EXT_CAP 0x0000000000000001ULL + +#define PCS_MII_ADV (FZC_MAC + 0x00010UL) +#define PCS_MII_ADV_NEXT_PAGE 0x0000000000008000ULL +#define PCS_MII_ADV_ACK 0x0000000000004000ULL +#define PCS_MII_ADV_REMOTE_FAULT 0x0000000000003000ULL +#define PCS_MII_ADV_ASM_DIR 0x0000000000000100ULL +#define PCS_MII_ADV_PAUSE 0x0000000000000080ULL +#define PCS_MII_ADV_HALF_DUPLEX 0x0000000000000040ULL +#define PCS_MII_ADV_FULL_DUPLEX 0x0000000000000020ULL + +#define PCS_MII_PARTNER (FZC_MAC + 0x00018UL) +#define PCS_MII_PARTNER_NEXT_PAGE 0x0000000000008000ULL +#define PCS_MII_PARTNER_ACK 0x0000000000004000ULL +#define PCS_MII_PARTNER_REMOTE_FAULT 0x0000000000002000ULL +#define PCS_MII_PARTNER_PAUSE 0x0000000000000180ULL +#define PCS_MII_PARTNER_HALF_DUPLEX 0x0000000000000040ULL +#define PCS_MII_PARTNER_FULL_DUPLEX 0x0000000000000020ULL + +#define PCS_CONF (FZC_MAC + 0x00020UL) +#define PCS_CONF_MASK 0x0000000000000040ULL +#define PCS_CONF_10MS_TMR_OVERRIDE 0x0000000000000020ULL +#define PCS_CONF_JITTER_STUDY 0x0000000000000018ULL +#define PCS_CONF_SIGDET_ACTIVE_LOW 0x0000000000000004ULL +#define PCS_CONF_SIGDET_OVERRIDE 0x0000000000000002ULL +#define PCS_CONF_ENABLE 0x0000000000000001ULL + +#define PCS_STATE (FZC_MAC + 0x00028UL) +#define PCS_STATE_D_PARTNER_FAIL 0x0000000020000000ULL +#define PCS_STATE_D_WAIT_C_CODES_ACK 0x0000000010000000ULL +#define PCS_STATE_D_SYNC_LOSS 0x0000000008000000ULL +#define PCS_STATE_D_NO_GOOD_C_CODES 0x0000000004000000ULL +#define PCS_STATE_D_SERDES 0x0000000002000000ULL +#define PCS_STATE_D_BREAKLINK_C_CODES 0x0000000001000000ULL +#define PCS_STATE_L_SIGDET 0x0000000000400000ULL +#define PCS_STATE_L_SYNC_LOSS 0x0000000000200000ULL +#define PCS_STATE_L_C_CODES 0x0000000000100000ULL +#define PCS_STATE_LINK_CFG_STATE 0x000000000001e000ULL +#define PCS_STATE_SEQ_DET_STATE 0x0000000000001800ULL +#define PCS_STATE_WORD_SYNC_STATE 0x0000000000000700ULL +#define PCS_STATE_NO_IDLE 0x000000000000000fULL + +#define PCS_INTERRUPT (FZC_MAC + 0x00030UL) +#define PCS_INTERRUPT_LSTATUS 0x0000000000000004ULL + +#define PCS_DPATH_MODE (FZC_MAC + 0x000a0UL) +#define PCS_DPATH_MODE_PCS 0x0000000000000000ULL +#define PCS_DPATH_MODE_MII 0x0000000000000002ULL +#define PCS_DPATH_MODE_LINKUP_F_ENAB 0x0000000000000001ULL + +#define PCS_PKT_CNT (FZC_MAC + 0x000c0UL) +#define PCS_PKT_CNT_RX 0x0000000007ff0000ULL +#define PCS_PKT_CNT_TX 0x00000000000007ffULL + +#define MIF_BB_MDC (FZC_MAC + 0x16000UL) +#define MIF_BB_MDC_CLK 0x0000000000000001ULL + +#define MIF_BB_MDO (FZC_MAC + 0x16008UL) +#define MIF_BB_MDO_DAT 0x0000000000000001ULL + +#define MIF_BB_MDO_EN (FZC_MAC + 0x16010UL) +#define MIF_BB_MDO_EN_VAL 0x0000000000000001ULL + +#define MIF_FRAME_OUTPUT (FZC_MAC + 0x16018UL) +#define MIF_FRAME_OUTPUT_ST 0x00000000c0000000ULL +#define MIF_FRAME_OUTPUT_ST_SHIFT 30 +#define MIF_FRAME_OUTPUT_OP_ADDR 0x0000000000000000ULL +#define MIF_FRAME_OUTPUT_OP_WRITE 0x0000000010000000ULL +#define MIF_FRAME_OUTPUT_OP_READ_INC 0x0000000020000000ULL +#define MIF_FRAME_OUTPUT_OP_READ 0x0000000030000000ULL +#define MIF_FRAME_OUTPUT_OP_SHIFT 28 +#define MIF_FRAME_OUTPUT_PORT 0x000000000f800000ULL +#define MIF_FRAME_OUTPUT_PORT_SHIFT 23 +#define MIF_FRAME_OUTPUT_REG 0x00000000007c0000ULL +#define MIF_FRAME_OUTPUT_REG_SHIFT 18 +#define MIF_FRAME_OUTPUT_TA 0x0000000000030000ULL +#define MIF_FRAME_OUTPUT_TA_SHIFT 16 +#define MIF_FRAME_OUTPUT_DATA 0x000000000000ffffULL +#define MIF_FRAME_OUTPUT_DATA_SHIFT 0 + +#define MDIO_ADDR_OP(port, dev, reg) \ + ((0 << MIF_FRAME_OUTPUT_ST_SHIFT) | \ + MIF_FRAME_OUTPUT_OP_ADDR | \ + (port << MIF_FRAME_OUTPUT_PORT_SHIFT) | \ + (dev << MIF_FRAME_OUTPUT_REG_SHIFT) | \ + (0x2 << MIF_FRAME_OUTPUT_TA_SHIFT) | \ + (reg << MIF_FRAME_OUTPUT_DATA_SHIFT)) + +#define MDIO_READ_OP(port, dev) \ + ((0 << MIF_FRAME_OUTPUT_ST_SHIFT) | \ + MIF_FRAME_OUTPUT_OP_READ | \ + (port << MIF_FRAME_OUTPUT_PORT_SHIFT) | \ + (dev << MIF_FRAME_OUTPUT_REG_SHIFT) | \ + (0x2 << MIF_FRAME_OUTPUT_TA_SHIFT)) + +#define MDIO_WRITE_OP(port, dev, data) \ + ((0 << MIF_FRAME_OUTPUT_ST_SHIFT) | \ + MIF_FRAME_OUTPUT_OP_WRITE | \ + (port << MIF_FRAME_OUTPUT_PORT_SHIFT) | \ + (dev << MIF_FRAME_OUTPUT_REG_SHIFT) | \ + (0x2 << MIF_FRAME_OUTPUT_TA_SHIFT) | \ + (data << MIF_FRAME_OUTPUT_DATA_SHIFT)) + +#define MII_READ_OP(port, reg) \ + ((1 << MIF_FRAME_OUTPUT_ST_SHIFT) | \ + (2 << MIF_FRAME_OUTPUT_OP_SHIFT) | \ + (port << MIF_FRAME_OUTPUT_PORT_SHIFT) | \ + (reg << MIF_FRAME_OUTPUT_REG_SHIFT) | \ + (0x2 << MIF_FRAME_OUTPUT_TA_SHIFT)) + +#define MII_WRITE_OP(port, reg, data) \ + ((1 << MIF_FRAME_OUTPUT_ST_SHIFT) | \ + (1 << MIF_FRAME_OUTPUT_OP_SHIFT) | \ + (port << MIF_FRAME_OUTPUT_PORT_SHIFT) | \ + (reg << MIF_FRAME_OUTPUT_REG_SHIFT) | \ + (0x2 << MIF_FRAME_OUTPUT_TA_SHIFT) | \ + (data << MIF_FRAME_OUTPUT_DATA_SHIFT)) + +#define MIF_CONFIG (FZC_MAC + 0x16020UL) +#define MIF_CONFIG_ATCA_GE 0x0000000000010000ULL +#define MIF_CONFIG_INDIRECT_MODE 0x0000000000008000ULL +#define MIF_CONFIG_POLL_PRT_PHYADDR 0x0000000000003c00ULL +#define MIF_CONFIG_POLL_DEV_REG_ADDR 0x00000000000003e0ULL +#define MIF_CONFIG_BB_MODE 0x0000000000000010ULL +#define MIF_CONFIG_POLL_EN 0x0000000000000008ULL +#define MIF_CONFIG_BB_SER_SEL 0x0000000000000006ULL +#define MIF_CONFIG_MANUAL_MODE 0x0000000000000001ULL + +#define MIF_POLL_STATUS (FZC_MAC + 0x16028UL) +#define MIF_POLL_STATUS_DATA 0x00000000ffff0000ULL +#define MIF_POLL_STATUS_STAT 0x000000000000ffffULL + +#define MIF_POLL_MASK (FZC_MAC + 0x16030UL) +#define MIF_POLL_MASK_VAL 0x000000000000ffffULL + +#define MIF_SM (FZC_MAC + 0x16038UL) +#define MIF_SM_PORT_ADDR 0x00000000001f0000ULL +#define MIF_SM_MDI_1 0x0000000000004000ULL +#define MIF_SM_MDI_0 0x0000000000002400ULL +#define MIF_SM_MDCLK 0x0000000000001000ULL +#define MIF_SM_MDO_EN 0x0000000000000800ULL +#define MIF_SM_MDO 0x0000000000000400ULL +#define MIF_SM_MDI 0x0000000000000200ULL +#define MIF_SM_CTL 0x00000000000001c0ULL +#define MIF_SM_EX 0x000000000000003fULL + +#define MIF_STATUS (FZC_MAC + 0x16040UL) +#define MIF_STATUS_MDINT1 0x0000000000000020ULL +#define MIF_STATUS_MDINT0 0x0000000000000010ULL + +#define MIF_MASK (FZC_MAC + 0x16048UL) +#define MIF_MASK_MDINT1 0x0000000000000020ULL +#define MIF_MASK_MDINT0 0x0000000000000010ULL +#define MIF_MASK_PEU_ERR 0x0000000000000008ULL +#define MIF_MASK_YC 0x0000000000000004ULL +#define MIF_MASK_XGE_ERR0 0x0000000000000002ULL +#define MIF_MASK_MIF_INIT_DONE 0x0000000000000001ULL + +#define ENET_SERDES_RESET (FZC_MAC + 0x14000UL) +#define ENET_SERDES_RESET_1 0x0000000000000002ULL +#define ENET_SERDES_RESET_0 0x0000000000000001ULL + +#define ENET_SERDES_CFG (FZC_MAC + 0x14008UL) +#define ENET_SERDES_BE_LOOPBACK 0x0000000000000002ULL +#define ENET_SERDES_CFG_FORCE_RDY 0x0000000000000001ULL + +#define ENET_SERDES_0_PLL_CFG (FZC_MAC + 0x14010UL) +#define ENET_SERDES_PLL_FBDIV0 0x0000000000000001ULL +#define ENET_SERDES_PLL_FBDIV1 0x0000000000000002ULL +#define ENET_SERDES_PLL_FBDIV2 0x0000000000000004ULL +#define ENET_SERDES_PLL_HRATE0 0x0000000000000008ULL +#define ENET_SERDES_PLL_HRATE1 0x0000000000000010ULL +#define ENET_SERDES_PLL_HRATE2 0x0000000000000020ULL +#define ENET_SERDES_PLL_HRATE3 0x0000000000000040ULL + +#define ENET_SERDES_0_CTRL_CFG (FZC_MAC + 0x14018UL) +#define ENET_SERDES_CTRL_SDET_0 0x0000000000000001ULL +#define ENET_SERDES_CTRL_SDET_1 0x0000000000000002ULL +#define ENET_SERDES_CTRL_SDET_2 0x0000000000000004ULL +#define ENET_SERDES_CTRL_SDET_3 0x0000000000000008ULL +#define ENET_SERDES_CTRL_EMPH_0 0x0000000000000070ULL +#define ENET_SERDES_CTRL_EMPH_0_SHIFT 4 +#define ENET_SERDES_CTRL_EMPH_1 0x0000000000000380ULL +#define ENET_SERDES_CTRL_EMPH_1_SHIFT 7 +#define ENET_SERDES_CTRL_EMPH_2 0x0000000000001c00ULL +#define ENET_SERDES_CTRL_EMPH_2_SHIFT 10 +#define ENET_SERDES_CTRL_EMPH_3 0x000000000000e000ULL +#define ENET_SERDES_CTRL_EMPH_3_SHIFT 13 +#define ENET_SERDES_CTRL_LADJ_0 0x0000000000070000ULL +#define ENET_SERDES_CTRL_LADJ_0_SHIFT 16 +#define ENET_SERDES_CTRL_LADJ_1 0x0000000000380000ULL +#define ENET_SERDES_CTRL_LADJ_1_SHIFT 19 +#define ENET_SERDES_CTRL_LADJ_2 0x0000000001c00000ULL +#define ENET_SERDES_CTRL_LADJ_2_SHIFT 22 +#define ENET_SERDES_CTRL_LADJ_3 0x000000000e000000ULL +#define ENET_SERDES_CTRL_LADJ_3_SHIFT 25 +#define ENET_SERDES_CTRL_RXITERM_0 0x0000000010000000ULL +#define ENET_SERDES_CTRL_RXITERM_1 0x0000000020000000ULL +#define ENET_SERDES_CTRL_RXITERM_2 0x0000000040000000ULL +#define ENET_SERDES_CTRL_RXITERM_3 0x0000000080000000ULL + +#define ENET_SERDES_0_TEST_CFG (FZC_MAC + 0x14020UL) +#define ENET_SERDES_TEST_MD_0 0x0000000000000003ULL +#define ENET_SERDES_TEST_MD_0_SHIFT 0 +#define ENET_SERDES_TEST_MD_1 0x000000000000000cULL +#define ENET_SERDES_TEST_MD_1_SHIFT 2 +#define ENET_SERDES_TEST_MD_2 0x0000000000000030ULL +#define ENET_SERDES_TEST_MD_2_SHIFT 4 +#define ENET_SERDES_TEST_MD_3 0x00000000000000c0ULL +#define ENET_SERDES_TEST_MD_3_SHIFT 6 + +#define ENET_TEST_MD_NO_LOOPBACK 0x0 +#define ENET_TEST_MD_EWRAP 0x1 +#define ENET_TEST_MD_PAD_LOOPBACK 0x2 +#define ENET_TEST_MD_REV_LOOPBACK 0x3 + +#define ENET_SERDES_1_PLL_CFG (FZC_MAC + 0x14028UL) +#define ENET_SERDES_1_CTRL_CFG (FZC_MAC + 0x14030UL) +#define ENET_SERDES_1_TEST_CFG (FZC_MAC + 0x14038UL) + +#define ENET_RGMII_CFG_REG (FZC_MAC + 0x14040UL) + +#define ESR_INT_SIGNALS (FZC_MAC + 0x14800UL) +#define ESR_INT_SIGNALS_ALL 0x00000000ffffffffULL +#define ESR_INT_SIGNALS_P0_BITS 0x0000000033e0000fULL +#define ESR_INT_SIGNALS_P1_BITS 0x000000000c1f00f0ULL +#define ESR_INT_SRDY0_P0 0x0000000020000000ULL +#define ESR_INT_DET0_P0 0x0000000010000000ULL +#define ESR_INT_SRDY0_P1 0x0000000008000000ULL +#define ESR_INT_DET0_P1 0x0000000004000000ULL +#define ESR_INT_XSRDY_P0 0x0000000002000000ULL +#define ESR_INT_XDP_P0_CH3 0x0000000001000000ULL +#define ESR_INT_XDP_P0_CH2 0x0000000000800000ULL +#define ESR_INT_XDP_P0_CH1 0x0000000000400000ULL +#define ESR_INT_XDP_P0_CH0 0x0000000000200000ULL +#define ESR_INT_XSRDY_P1 0x0000000000100000ULL +#define ESR_INT_XDP_P1_CH3 0x0000000000080000ULL +#define ESR_INT_XDP_P1_CH2 0x0000000000040000ULL +#define ESR_INT_XDP_P1_CH1 0x0000000000020000ULL +#define ESR_INT_XDP_P1_CH0 0x0000000000010000ULL +#define ESR_INT_SLOSS_P1_CH3 0x0000000000000080ULL +#define ESR_INT_SLOSS_P1_CH2 0x0000000000000040ULL +#define ESR_INT_SLOSS_P1_CH1 0x0000000000000020ULL +#define ESR_INT_SLOSS_P1_CH0 0x0000000000000010ULL +#define ESR_INT_SLOSS_P0_CH3 0x0000000000000008ULL +#define ESR_INT_SLOSS_P0_CH2 0x0000000000000004ULL +#define ESR_INT_SLOSS_P0_CH1 0x0000000000000002ULL +#define ESR_INT_SLOSS_P0_CH0 0x0000000000000001ULL + +#define ESR_DEBUG_SEL (FZC_MAC + 0x14808UL) +#define ESR_DEBUG_SEL_VAL 0x000000000000003fULL + +/* SerDes registers behind MIF */ +#define NIU_ESR_DEV_ADDR 0x1e +#define ESR_BASE 0x0000 + +#define ESR_RXTX_COMM_CTRL_L (ESR_BASE + 0x0000) +#define ESR_RXTX_COMM_CTRL_H (ESR_BASE + 0x0001) + +#define ESR_RXTX_RESET_CTRL_L (ESR_BASE + 0x0002) +#define ESR_RXTX_RESET_CTRL_H (ESR_BASE + 0x0003) + +#define ESR_RX_POWER_CTRL_L (ESR_BASE + 0x0004) +#define ESR_RX_POWER_CTRL_H (ESR_BASE + 0x0005) + +#define ESR_TX_POWER_CTRL_L (ESR_BASE + 0x0006) +#define ESR_TX_POWER_CTRL_H (ESR_BASE + 0x0007) + +#define ESR_MISC_POWER_CTRL_L (ESR_BASE + 0x0008) +#define ESR_MISC_POWER_CTRL_H (ESR_BASE + 0x0009) + +#define ESR_RXTX_CTRL_L(CHAN) (ESR_BASE + 0x0080 + (CHAN) * 0x10) +#define ESR_RXTX_CTRL_H(CHAN) (ESR_BASE + 0x0081 + (CHAN) * 0x10) +#define ESR_RXTX_CTRL_BIASCNTL 0x80000000 +#define ESR_RXTX_CTRL_RESV1 0x7c000000 +#define ESR_RXTX_CTRL_TDENFIFO 0x02000000 +#define ESR_RXTX_CTRL_TDWS20 0x01000000 +#define ESR_RXTX_CTRL_VMUXLO 0x00c00000 +#define ESR_RXTX_CTRL_VMUXLO_SHIFT 22 +#define ESR_RXTX_CTRL_VPULSELO 0x00300000 +#define ESR_RXTX_CTRL_VPULSELO_SHIFT 20 +#define ESR_RXTX_CTRL_RESV2 0x000f0000 +#define ESR_RXTX_CTRL_RESV3 0x0000c000 +#define ESR_RXTX_CTRL_RXPRESWIN 0x00003000 +#define ESR_RXTX_CTRL_RXPRESWIN_SHIFT 12 +#define ESR_RXTX_CTRL_RESV4 0x00000800 +#define ESR_RXTX_CTRL_RISEFALL 0x00000700 +#define ESR_RXTX_CTRL_RISEFALL_SHIFT 8 +#define ESR_RXTX_CTRL_RESV5 0x000000fe +#define ESR_RXTX_CTRL_ENSTRETCH 0x00000001 + +#define ESR_RXTX_TUNING_L(CHAN) (ESR_BASE + 0x0082 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING_H(CHAN) (ESR_BASE + 0x0083 + (CHAN) * 0x10) + +#define ESR_RX_SYNCCHAR_L(CHAN) (ESR_BASE + 0x0084 + (CHAN) * 0x10) +#define ESR_RX_SYNCCHAR_H(CHAN) (ESR_BASE + 0x0085 + (CHAN) * 0x10) + +#define ESR_RXTX_TEST_L(CHAN) (ESR_BASE + 0x0086 + (CHAN) * 0x10) +#define ESR_RXTX_TEST_H(CHAN) (ESR_BASE + 0x0087 + (CHAN) * 0x10) + +#define ESR_GLUE_CTRL0_L(CHAN) (ESR_BASE + 0x0088 + (CHAN) * 0x10) +#define ESR_GLUE_CTRL0_H(CHAN) (ESR_BASE + 0x0089 + (CHAN) * 0x10) +#define ESR_GLUE_CTRL0_RESV1 0xf8000000 +#define ESR_GLUE_CTRL0_BLTIME 0x07000000 +#define ESR_GLUE_CTRL0_BLTIME_SHIFT 24 +#define ESR_GLUE_CTRL0_RESV2 0x00ff0000 +#define ESR_GLUE_CTRL0_RXLOS_TEST 0x00008000 +#define ESR_GLUE_CTRL0_RESV3 0x00004000 +#define ESR_GLUE_CTRL0_RXLOSENAB 0x00002000 +#define ESR_GLUE_CTRL0_FASTRESYNC 0x00001000 +#define ESR_GLUE_CTRL0_SRATE 0x00000f00 +#define ESR_GLUE_CTRL0_SRATE_SHIFT 8 +#define ESR_GLUE_CTRL0_THCNT 0x000000ff +#define ESR_GLUE_CTRL0_THCNT_SHIFT 0 + +#define BLTIME_64_CYCLES 0 +#define BLTIME_128_CYCLES 1 +#define BLTIME_256_CYCLES 2 +#define BLTIME_300_CYCLES 3 +#define BLTIME_384_CYCLES 4 +#define BLTIME_512_CYCLES 5 +#define BLTIME_1024_CYCLES 6 +#define BLTIME_2048_CYCLES 7 + +#define ESR_GLUE_CTRL1_L(CHAN) (ESR_BASE + 0x008a + (CHAN) * 0x10) +#define ESR_GLUE_CTRL1_H(CHAN) (ESR_BASE + 0x008b + (CHAN) * 0x10) +#define ESR_RXTX_TUNING1_L(CHAN) (ESR_BASE + 0x00c2 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING1_H(CHAN) (ESR_BASE + 0x00c2 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING2_L(CHAN) (ESR_BASE + 0x0102 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING2_H(CHAN) (ESR_BASE + 0x0102 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING3_L(CHAN) (ESR_BASE + 0x0142 + (CHAN) * 0x10) +#define ESR_RXTX_TUNING3_H(CHAN) (ESR_BASE + 0x0142 + (CHAN) * 0x10) + +#define NIU_ESR2_DEV_ADDR 0x1e +#define ESR2_BASE 0x8000 + +#define ESR2_TI_PLL_CFG_L (ESR2_BASE + 0x000) +#define ESR2_TI_PLL_CFG_H (ESR2_BASE + 0x001) +#define PLL_CFG_STD 0x00000c00 +#define PLL_CFG_STD_SHIFT 10 +#define PLL_CFG_LD 0x00000300 +#define PLL_CFG_LD_SHIFT 8 +#define PLL_CFG_MPY 0x0000001e +#define PLL_CFG_MPY_SHIFT 1 +#define PLL_CFG_ENPLL 0x00000001 + +#define ESR2_TI_PLL_STS_L (ESR2_BASE + 0x002) +#define ESR2_TI_PLL_STS_H (ESR2_BASE + 0x003) +#define PLL_STS_LOCK 0x00000001 + +#define ESR2_TI_PLL_TEST_CFG_L (ESR2_BASE + 0x004) +#define ESR2_TI_PLL_TEST_CFG_H (ESR2_BASE + 0x005) +#define PLL_TEST_INVPATT 0x00004000 +#define PLL_TEST_RATE 0x00003000 +#define PLL_TEST_RATE_SHIFT 12 +#define PLL_TEST_CFG_ENBSAC 0x00000400 +#define PLL_TEST_CFG_ENBSRX 0x00000200 +#define PLL_TEST_CFG_ENBSTX 0x00000100 +#define PLL_TEST_CFG_LOOPBACK_PAD 0x00000040 +#define PLL_TEST_CFG_LOOPBACK_CML_DIS 0x00000080 +#define PLL_TEST_CFG_LOOPBACK_CML_EN 0x000000c0 +#define PLL_TEST_CFG_CLKBYP 0x00000030 +#define PLL_TEST_CFG_CLKBYP_SHIFT 4 +#define PLL_TEST_CFG_EN_RXPATT 0x00000008 +#define PLL_TEST_CFG_EN_TXPATT 0x00000004 +#define PLL_TEST_CFG_TPATT 0x00000003 +#define PLL_TEST_CFG_TPATT_SHIFT 0 + +#define ESR2_TI_PLL_TX_CFG_L(CHAN) (ESR2_BASE + 0x100 + (CHAN) * 4) +#define ESR2_TI_PLL_TX_CFG_H(CHAN) (ESR2_BASE + 0x101 + (CHAN) * 4) +#define PLL_TX_CFG_RDTCT 0x00600000 +#define PLL_TX_CFG_RDTCT_SHIFT 21 +#define PLL_TX_CFG_ENIDL 0x00100000 +#define PLL_TX_CFG_BSTX 0x00020000 +#define PLL_TX_CFG_ENFTP 0x00010000 +#define PLL_TX_CFG_DE 0x0000f000 +#define PLL_TX_CFG_DE_SHIFT 12 +#define PLL_TX_CFG_SWING_125MV 0x00000000 +#define PLL_TX_CFG_SWING_250MV 0x00000200 +#define PLL_TX_CFG_SWING_500MV 0x00000400 +#define PLL_TX_CFG_SWING_625MV 0x00000600 +#define PLL_TX_CFG_SWING_750MV 0x00000800 +#define PLL_TX_CFG_SWING_1000MV 0x00000a00 +#define PLL_TX_CFG_SWING_1250MV 0x00000c00 +#define PLL_TX_CFG_SWING_1375MV 0x00000e00 +#define PLL_TX_CFG_CM 0x00000100 +#define PLL_TX_CFG_INVPAIR 0x00000080 +#define PLL_TX_CFG_RATE 0x00000060 +#define PLL_TX_CFG_RATE_SHIFT 5 +#define PLL_TX_CFG_BUSWIDTH 0x0000001c +#define PLL_TX_CFG_BUSWIDTH_SHIFT 2 +#define PLL_TX_CFG_ENTEST 0x00000002 +#define PLL_TX_CFG_ENTX 0x00000001 + +#define ESR2_TI_PLL_TX_STS_L(CHAN) (ESR2_BASE + 0x102 + (CHAN) * 4) +#define ESR2_TI_PLL_TX_STS_H(CHAN) (ESR2_BASE + 0x103 + (CHAN) * 4) +#define PLL_TX_STS_RDTCTIP 0x00000002 +#define PLL_TX_STS_TESTFAIL 0x00000001 + +#define ESR2_TI_PLL_RX_CFG_L(CHAN) (ESR2_BASE + 0x120 + (CHAN) * 4) +#define ESR2_TI_PLL_RX_CFG_H(CHAN) (ESR2_BASE + 0x121 + (CHAN) * 4) +#define PLL_RX_CFG_BSINRXN 0x02000000 +#define PLL_RX_CFG_BSINRXP 0x01000000 +#define PLL_RX_CFG_EQ_MAX_LF 0x00000000 +#define PLL_RX_CFG_EQ_LP_ADAPTIVE 0x00080000 +#define PLL_RX_CFG_EQ_LP_1084MHZ 0x00400000 +#define PLL_RX_CFG_EQ_LP_805MHZ 0x00480000 +#define PLL_RX_CFG_EQ_LP_573MHZ 0x00500000 +#define PLL_RX_CFG_EQ_LP_402MHZ 0x00580000 +#define PLL_RX_CFG_EQ_LP_304MHZ 0x00600000 +#define PLL_RX_CFG_EQ_LP_216MHZ 0x00680000 +#define PLL_RX_CFG_EQ_LP_156MHZ 0x00700000 +#define PLL_RX_CFG_EQ_LP_135MHZ 0x00780000 +#define PLL_RX_CFG_EQ_SHIFT 19 +#define PLL_RX_CFG_CDR 0x00070000 +#define PLL_RX_CFG_CDR_SHIFT 16 +#define PLL_RX_CFG_LOS_DIS 0x00000000 +#define PLL_RX_CFG_LOS_HTHRESH 0x00004000 +#define PLL_RX_CFG_LOS_LTHRESH 0x00008000 +#define PLL_RX_CFG_ALIGN_DIS 0x00000000 +#define PLL_RX_CFG_ALIGN_ENA 0x00001000 +#define PLL_RX_CFG_ALIGN_JOG 0x00002000 +#define PLL_RX_CFG_TERM_VDDT 0x00000000 +#define PLL_RX_CFG_TERM_0P8VDDT 0x00000100 +#define PLL_RX_CFG_TERM_FLOAT 0x00000300 +#define PLL_RX_CFG_INVPAIR 0x00000080 +#define PLL_RX_CFG_RATE 0x00000060 +#define PLL_RX_CFG_RATE_SHIFT 5 +#define PLL_RX_CFG_BUSWIDTH 0x0000001c +#define PLL_RX_CFG_BUSWIDTH_SHIFT 2 +#define PLL_RX_CFG_ENTEST 0x00000002 +#define PLL_RX_CFG_ENRX 0x00000001 + +#define ESR2_TI_PLL_RX_STS_L(CHAN) (ESR2_BASE + 0x122 + (CHAN) * 4) +#define ESR2_TI_PLL_RX_STS_H(CHAN) (ESR2_BASE + 0x123 + (CHAN) * 4) +#define PLL_RX_STS_CRCIDTCT 0x00000200 +#define PLL_RX_STS_CWDTCT 0x00000100 +#define PLL_RX_STS_BSRXN 0x00000020 +#define PLL_RX_STS_BSRXP 0x00000010 +#define PLL_RX_STS_LOSDTCT 0x00000008 +#define PLL_RX_STS_ODDCG 0x00000004 +#define PLL_RX_STS_SYNC 0x00000002 +#define PLL_RX_STS_TESTFAIL 0x00000001 + +#define ENET_VLAN_TBL(IDX) (FZC_FFLP + 0x00000UL + (IDX) * 8UL) +#define ENET_VLAN_TBL_PARITY1 0x0000000000020000ULL +#define ENET_VLAN_TBL_PARITY0 0x0000000000010000ULL +#define ENET_VLAN_TBL_VPR 0x0000000000000008ULL +#define ENET_VLAN_TBL_VLANRDCTBLN 0x0000000000000007ULL +#define ENET_VLAN_TBL_SHIFT(PORT) ((PORT) * 4) + +#define ENET_VLAN_TBL_NUM_ENTRIES 4096 + +#define FFLP_VLAN_PAR_ERR (FZC_FFLP + 0x0800UL) +#define FFLP_VLAN_PAR_ERR_ERR 0x0000000080000000ULL +#define FFLP_VLAN_PAR_ERR_M_ERR 0x0000000040000000ULL +#define FFLP_VLAN_PAR_ERR_ADDR 0x000000003ffc0000ULL +#define FFLP_VLAN_PAR_ERR_DATA 0x000000000003ffffULL + +#define L2_CLS(IDX) (FZC_FFLP + 0x20000UL + (IDX) * 8UL) +#define L2_CLS_VLD 0x0000000000010000ULL +#define L2_CLS_ETYPE 0x000000000000ffffULL +#define L2_CLS_ETYPE_SHIFT 0 + +#define L3_CLS(IDX) (FZC_FFLP + 0x20010UL + (IDX) * 8UL) +#define L3_CLS_VALID 0x0000000002000000ULL +#define L3_CLS_IPVER 0x0000000001000000ULL +#define L3_CLS_PID 0x0000000000ff0000ULL +#define L3_CLS_PID_SHIFT 16 +#define L3_CLS_TOSMASK 0x000000000000ff00ULL +#define L3_CLS_TOSMASK_SHIFT 8 +#define L3_CLS_TOS 0x00000000000000ffULL +#define L3_CLS_TOS_SHIFT 0 + +#define TCAM_KEY(IDX) (FZC_FFLP + 0x20030UL + (IDX) * 8UL) +#define TCAM_KEY_DISC 0x0000000000000008ULL +#define TCAM_KEY_TSEL 0x0000000000000004ULL +#define TCAM_KEY_IPADDR 0x0000000000000001ULL + +#define TCAM_KEY_0 (FZC_FFLP + 0x20090UL) +#define TCAM_KEY_0_KEY 0x00000000000000ffULL /* bits 192-199 */ + +#define TCAM_KEY_1 (FZC_FFLP + 0x20098UL) +#define TCAM_KEY_1_KEY 0xffffffffffffffffULL /* bits 128-191 */ + +#define TCAM_KEY_2 (FZC_FFLP + 0x200a0UL) +#define TCAM_KEY_2_KEY 0xffffffffffffffffULL /* bits 64-127 */ + +#define TCAM_KEY_3 (FZC_FFLP + 0x200a8UL) +#define TCAM_KEY_3_KEY 0xffffffffffffffffULL /* bits 0-63 */ + +#define TCAM_KEY_MASK_0 (FZC_FFLP + 0x200b0UL) +#define TCAM_KEY_MASK_0_KEY_SEL 0x00000000000000ffULL /* bits 192-199 */ + +#define TCAM_KEY_MASK_1 (FZC_FFLP + 0x200b8UL) +#define TCAM_KEY_MASK_1_KEY_SEL 0xffffffffffffffffULL /* bits 128-191 */ + +#define TCAM_KEY_MASK_2 (FZC_FFLP + 0x200c0UL) +#define TCAM_KEY_MASK_2_KEY_SEL 0xffffffffffffffffULL /* bits 64-127 */ + +#define TCAM_KEY_MASK_3 (FZC_FFLP + 0x200c8UL) +#define TCAM_KEY_MASK_3_KEY_SEL 0xffffffffffffffffULL /* bits 0-63 */ + +#define TCAM_CTL (FZC_FFLP + 0x200d0UL) +#define TCAM_CTL_RWC 0x00000000001c0000ULL +#define TCAM_CTL_RWC_TCAM_WRITE 0x0000000000000000ULL +#define TCAM_CTL_RWC_TCAM_READ 0x0000000000040000ULL +#define TCAM_CTL_RWC_TCAM_COMPARE 0x0000000000080000ULL +#define TCAM_CTL_RWC_RAM_WRITE 0x0000000000100000ULL +#define TCAM_CTL_RWC_RAM_READ 0x0000000000140000ULL +#define TCAM_CTL_STAT 0x0000000000020000ULL +#define TCAM_CTL_MATCH 0x0000000000010000ULL +#define TCAM_CTL_LOC 0x00000000000003ffULL + +#define TCAM_ERR (FZC_FFLP + 0x200d8UL) +#define TCAM_ERR_ERR 0x0000000080000000ULL +#define TCAM_ERR_P_ECC 0x0000000040000000ULL +#define TCAM_ERR_MULT 0x0000000020000000ULL +#define TCAM_ERR_ADDR 0x0000000000ff0000ULL +#define TCAM_ERR_SYNDROME 0x000000000000ffffULL + +#define HASH_LOOKUP_ERR_LOG1 (FZC_FFLP + 0x200e0UL) +#define HASH_LOOKUP_ERR_LOG1_ERR 0x0000000000000008ULL +#define HASH_LOOKUP_ERR_LOG1_MULT_LK 0x0000000000000004ULL +#define HASH_LOOKUP_ERR_LOG1_CU 0x0000000000000002ULL +#define HASH_LOOKUP_ERR_LOG1_MULT_BIT 0x0000000000000001ULL + +#define HASH_LOOKUP_ERR_LOG2 (FZC_FFLP + 0x200e8UL) +#define HASH_LOOKUP_ERR_LOG2_H1 0x000000007ffff800ULL +#define HASH_LOOKUP_ERR_LOG2_SUBAREA 0x0000000000000700ULL +#define HASH_LOOKUP_ERR_LOG2_SYNDROME 0x00000000000000ffULL + +#define FFLP_CFG_1 (FZC_FFLP + 0x20100UL) +#define FFLP_CFG_1_TCAM_DIS 0x0000000004000000ULL +#define FFLP_CFG_1_PIO_DBG_SEL 0x0000000003800000ULL +#define FFLP_CFG_1_PIO_FIO_RST 0x0000000000400000ULL +#define FFLP_CFG_1_PIO_FIO_LAT 0x0000000000300000ULL +#define FFLP_CFG_1_CAMLAT 0x00000000000f0000ULL +#define FFLP_CFG_1_CAMLAT_SHIFT 16 +#define FFLP_CFG_1_CAMRATIO 0x000000000000f000ULL +#define FFLP_CFG_1_CAMRATIO_SHIFT 12 +#define FFLP_CFG_1_FCRAMRATIO 0x0000000000000f00ULL +#define FFLP_CFG_1_FCRAMRATIO_SHIFT 8 +#define FFLP_CFG_1_FCRAMOUTDR_MASK 0x00000000000000f0ULL +#define FFLP_CFG_1_FCRAMOUTDR_NORMAL 0x0000000000000000ULL +#define FFLP_CFG_1_FCRAMOUTDR_STRONG 0x0000000000000050ULL +#define FFLP_CFG_1_FCRAMOUTDR_WEAK 0x00000000000000a0ULL +#define FFLP_CFG_1_FCRAMQS 0x0000000000000008ULL +#define FFLP_CFG_1_ERRORDIS 0x0000000000000004ULL +#define FFLP_CFG_1_FFLPINITDONE 0x0000000000000002ULL +#define FFLP_CFG_1_LLCSNAP 0x0000000000000001ULL + +#define DEFAULT_FCRAMRATIO 10 + +#define DEFAULT_TCAM_LATENCY 4 +#define DEFAULT_TCAM_ACCESS_RATIO 10 + +#define TCP_CFLAG_MSK (FZC_FFLP + 0x20108UL) +#define TCP_CFLAG_MSK_MASK 0x0000000000000fffULL + +#define FCRAM_REF_TMR (FZC_FFLP + 0x20110UL) +#define FCRAM_REF_TMR_MAX 0x00000000ffff0000ULL +#define FCRAM_REF_TMR_MAX_SHIFT 16 +#define FCRAM_REF_TMR_MIN 0x000000000000ffffULL +#define FCRAM_REF_TMR_MIN_SHIFT 0 + +#define DEFAULT_FCRAM_REFRESH_MAX 512 +#define DEFAULT_FCRAM_REFRESH_MIN 512 + +#define FCRAM_FIO_ADDR (FZC_FFLP + 0x20118UL) +#define FCRAM_FIO_ADDR_ADDR 0x00000000000000ffULL + +#define FCRAM_FIO_DAT (FZC_FFLP + 0x20120UL) +#define FCRAM_FIO_DAT_DATA 0x000000000000ffffULL + +#define FCRAM_ERR_TST0 (FZC_FFLP + 0x20128UL) +#define FCRAM_ERR_TST0_SYND 0x00000000000000ffULL + +#define FCRAM_ERR_TST1 (FZC_FFLP + 0x20130UL) +#define FCRAM_ERR_TST1_DAT 0x00000000ffffffffULL + +#define FCRAM_ERR_TST2 (FZC_FFLP + 0x20138UL) +#define FCRAM_ERR_TST2_DAT 0x00000000ffffffffULL + +#define FFLP_ERR_MASK (FZC_FFLP + 0x20140UL) +#define FFLP_ERR_MASK_HSH_TBL_DAT 0x00000000000007f8ULL +#define FFLP_ERR_MASK_HSH_TBL_LKUP 0x0000000000000004ULL +#define FFLP_ERR_MASK_TCAM 0x0000000000000002ULL +#define FFLP_ERR_MASK_VLAN 0x0000000000000001ULL + +#define FFLP_DBG_TRAIN_VCT (FZC_FFLP + 0x20148UL) +#define FFLP_DBG_TRAIN_VCT_VECTOR 0x00000000ffffffffULL + +#define FCRAM_PHY_RD_LAT (FZC_FFLP + 0x20150UL) +#define FCRAM_PHY_RD_LAT_LAT 0x00000000000000ffULL + +/* Ethernet TCAM format */ +#define TCAM_ETHKEY0_RESV1 0xffffffffffffff00ULL +#define TCAM_ETHKEY0_CLASS_CODE 0x00000000000000f8ULL +#define TCAM_ETHKEY0_CLASS_CODE_SHIFT 3 +#define TCAM_ETHKEY0_RESV2 0x0000000000000007ULL +#define TCAM_ETHKEY1_FRAME_BYTE0_7(NUM) (0xff << ((7 - NUM) * 8)) +#define TCAM_ETHKEY2_FRAME_BYTE8 0xff00000000000000ULL +#define TCAM_ETHKEY2_FRAME_BYTE8_SHIFT 56 +#define TCAM_ETHKEY2_FRAME_BYTE9 0x00ff000000000000ULL +#define TCAM_ETHKEY2_FRAME_BYTE9_SHIFT 48 +#define TCAM_ETHKEY2_FRAME_BYTE10 0x0000ff0000000000ULL +#define TCAM_ETHKEY2_FRAME_BYTE10_SHIFT 40 +#define TCAM_ETHKEY2_FRAME_RESV 0x000000ffffffffffULL +#define TCAM_ETHKEY3_FRAME_RESV 0xffffffffffffffffULL + +/* IPV4 TCAM format */ +#define TCAM_V4KEY0_RESV1 0xffffffffffffff00ULL +#define TCAM_V4KEY0_CLASS_CODE 0x00000000000000f8ULL +#define TCAM_V4KEY0_CLASS_CODE_SHIFT 3 +#define TCAM_V4KEY0_RESV2 0x0000000000000007ULL +#define TCAM_V4KEY1_L2RDCNUM 0xf800000000000000ULL +#define TCAM_V4KEY1_L2RDCNUM_SHIFT 59 +#define TCAM_V4KEY1_NOPORT 0x0400000000000000ULL +#define TCAM_V4KEY1_RESV 0x03ffffffffffffffULL +#define TCAM_V4KEY2_RESV 0xffff000000000000ULL +#define TCAM_V4KEY2_TOS 0x0000ff0000000000ULL +#define TCAM_V4KEY2_TOS_SHIFT 40 +#define TCAM_V4KEY2_PROTO 0x000000ff00000000ULL +#define TCAM_V4KEY2_PROTO_SHIFT 32 +#define TCAM_V4KEY2_PORT_SPI 0x00000000ffffffffULL +#define TCAM_V4KEY2_PORT_SPI_SHIFT 0 +#define TCAM_V4KEY3_SADDR 0xffffffff00000000ULL +#define TCAM_V4KEY3_SADDR_SHIFT 32 +#define TCAM_V4KEY3_DADDR 0x00000000ffffffffULL +#define TCAM_V4KEY3_DADDR_SHIFT 0 + +/* IPV6 TCAM format */ +#define TCAM_V6KEY0_RESV1 0xffffffffffffff00ULL +#define TCAM_V6KEY0_CLASS_CODE 0x00000000000000f8ULL +#define TCAM_V6KEY0_CLASS_CODE_SHIFT 3 +#define TCAM_V6KEY0_RESV2 0x0000000000000007ULL +#define TCAM_V6KEY1_L2RDCNUM 0xf800000000000000ULL +#define TCAM_V6KEY1_L2RDCNUM_SHIFT 59 +#define TCAM_V6KEY1_NOPORT 0x0400000000000000ULL +#define TCAM_V6KEY1_RESV 0x03ff000000000000ULL +#define TCAM_V6KEY1_TOS 0x0000ff0000000000ULL +#define TCAM_V6KEY1_TOS_SHIFT 40 +#define TCAM_V6KEY1_NEXT_HDR 0x000000ff00000000ULL +#define TCAM_V6KEY1_NEXT_HDR_SHIFT 32 +#define TCAM_V6KEY1_PORT_SPI 0x00000000ffffffffULL +#define TCAM_V6KEY1_PORT_SPI_SHIFT 0 +#define TCAM_V6KEY2_ADDR_HIGH 0xffffffffffffffffULL +#define TCAM_V6KEY3_ADDR_LOW 0xffffffffffffffffULL + +#define TCAM_ASSOCDATA_SYNDROME 0x000003fffc000000ULL +#define TCAM_ASSOCDATA_SYNDROME_SHIFT 26 +#define TCAM_ASSOCDATA_ZFID 0x0000000003ffc000ULL +#define TCAM_ASSOCDATA_ZFID_SHIFT 14 +#define TCAM_ASSOCDATA_V4_ECC_OK 0x0000000000002000ULL +#define TCAM_ASSOCDATA_DISC 0x0000000000001000ULL +#define TCAM_ASSOCDATA_TRES_MASK 0x0000000000000c00ULL +#define TCAM_ASSOCDATA_TRES_USE_L2RDC 0x0000000000000000ULL +#define TCAM_ASSOCDATA_TRES_USE_OFFSET 0x0000000000000400ULL +#define TCAM_ASSOCDATA_TRES_OVR_RDC 0x0000000000000800ULL +#define TCAM_ASSOCDATA_TRES_OVR_RDC_OFF 0x0000000000000c00ULL +#define TCAM_ASSOCDATA_RDCTBL 0x0000000000000380ULL +#define TCAM_ASSOCDATA_RDCTBL_SHIFT 7 +#define TCAM_ASSOCDATA_OFFSET 0x000000000000007cULL +#define TCAM_ASSOCDATA_OFFSET_SHIFT 2 +#define TCAM_ASSOCDATA_ZFVLD 0x0000000000000002ULL +#define TCAM_ASSOCDATA_AGE 0x0000000000000001ULL + +#define FLOW_KEY(IDX) (FZC_FFLP + 0x40000UL + (IDX) * 8UL) +#define FLOW_KEY_PORT 0x0000000000000200ULL +#define FLOW_KEY_L2DA 0x0000000000000100ULL +#define FLOW_KEY_VLAN 0x0000000000000080ULL +#define FLOW_KEY_IPSA 0x0000000000000040ULL +#define FLOW_KEY_IPDA 0x0000000000000020ULL +#define FLOW_KEY_PROTO 0x0000000000000010ULL +#define FLOW_KEY_L4_0 0x000000000000000cULL +#define FLOW_KEY_L4_0_SHIFT 2 +#define FLOW_KEY_L4_1 0x0000000000000003ULL +#define FLOW_KEY_L4_1_SHIFT 0 + +#define FLOW_KEY_L4_NONE 0x0 +#define FLOW_KEY_L4_RESV 0x1 +#define FLOW_KEY_L4_BYTE12 0x2 +#define FLOW_KEY_L4_BYTE56 0x3 + +#define H1POLY (FZC_FFLP + 0x40060UL) +#define H1POLY_INITVAL 0x00000000ffffffffULL + +#define H2POLY (FZC_FFLP + 0x40068UL) +#define H2POLY_INITVAL 0x000000000000ffffULL + +#define FLW_PRT_SEL(IDX) (FZC_FFLP + 0x40070UL + (IDX) * 8UL) +#define FLW_PRT_SEL_EXT 0x0000000000010000ULL +#define FLW_PRT_SEL_MASK 0x0000000000001f00ULL +#define FLW_PRT_SEL_MASK_SHIFT 8 +#define FLW_PRT_SEL_BASE 0x000000000000001fULL +#define FLW_PRT_SEL_BASE_SHIFT 0 + +#define HASH_TBL_ADDR(IDX) (FFLP + 0x00000UL + (IDX) * 8192UL) +#define HASH_TBL_ADDR_AUTOINC 0x0000000000800000ULL +#define HASH_TBL_ADDR_ADDR 0x00000000007fffffULL + +#define HASH_TBL_DATA(IDX) (FFLP + 0x00008UL + (IDX) * 8192UL) +#define HASH_TBL_DATA_DATA 0xffffffffffffffffULL + +/* FCRAM hash table entries are up to 8 64-bit words in size. + * The layout of each entry is determined by the settings in the + * first word, which is the header. + * + * The indexing is controllable per partition (there is one partition + * per RDC group, thus a total of eight) using the BASE and MASK fields + * of FLW_PRT_SEL above. + */ +#define FCRAM_SIZE 0x800000 +#define FCRAM_NUM_PARTITIONS 8 + +/* Generic HASH entry header, used for all non-optimized formats. */ +#define HASH_HEADER_FMT 0x8000000000000000ULL +#define HASH_HEADER_EXT 0x4000000000000000ULL +#define HASH_HEADER_VALID 0x2000000000000000ULL +#define HASH_HEADER_RESVD 0x1000000000000000ULL +#define HASH_HEADER_L2_DADDR 0x0ffffffffffff000ULL +#define HASH_HEADER_L2_DADDR_SHIFT 12 +#define HASH_HEADER_VLAN 0x0000000000000fffULL +#define HASH_HEADER_VLAN_SHIFT 0 + +/* Optimized format, just a header with a special layout defined below. + * Set FMT and EXT both to zero to indicate this layout is being used. + */ +#define HASH_OPT_HEADER_FMT 0x8000000000000000ULL +#define HASH_OPT_HEADER_EXT 0x4000000000000000ULL +#define HASH_OPT_HEADER_VALID 0x2000000000000000ULL +#define HASH_OPT_HEADER_RDCOFF 0x1f00000000000000ULL +#define HASH_OPT_HEADER_RDCOFF_SHIFT 56 +#define HASH_OPT_HEADER_HASH2 0x00ffff0000000000ULL +#define HASH_OPT_HEADER_HASH2_SHIFT 40 +#define HASH_OPT_HEADER_RESVD 0x000000ff00000000ULL +#define HASH_OPT_HEADER_USERINFO 0x00000000ffffffffULL +#define HASH_OPT_HEADER_USERINFO_SHIFT 0 + +/* Port and protocol word used for ipv4 and ipv6 layouts. */ +#define HASH_PORT_DPORT 0xffff000000000000ULL +#define HASH_PORT_DPORT_SHIFT 48 +#define HASH_PORT_SPORT 0x0000ffff00000000ULL +#define HASH_PORT_SPORT_SHIFT 32 +#define HASH_PORT_PROTO 0x00000000ff000000ULL +#define HASH_PORT_PROTO_SHIFT 24 +#define HASH_PORT_PORT_OFF 0x0000000000c00000ULL +#define HASH_PORT_PORT_OFF_SHIFT 22 +#define HASH_PORT_PORT_RESV 0x00000000003fffffULL + +/* Action word used for ipv4 and ipv6 layouts. */ +#define HASH_ACTION_RESV1 0xe000000000000000ULL +#define HASH_ACTION_RDCOFF 0x1f00000000000000ULL +#define HASH_ACTION_RDCOFF_SHIFT 56 +#define HASH_ACTION_ZFVALID 0x0080000000000000ULL +#define HASH_ACTION_RESV2 0x0070000000000000ULL +#define HASH_ACTION_ZFID 0x000fff0000000000ULL +#define HASH_ACTION_ZFID_SHIFT 40 +#define HASH_ACTION_RESV3 0x000000ff00000000ULL +#define HASH_ACTION_USERINFO 0x00000000ffffffffULL +#define HASH_ACTION_USERINFO_SHIFT 0 + +/* IPV4 address word. Addresses are in network endian. */ +#define HASH_IP4ADDR_SADDR 0xffffffff00000000ULL +#define HASH_IP4ADDR_SADDR_SHIFT 32 +#define HASH_IP4ADDR_DADDR 0x00000000ffffffffULL +#define HASH_IP4ADDR_DADDR_SHIFT 0 + +/* IPV6 address layout is 4 words, first two are saddr, next two + * are daddr. Addresses are in network endian. + */ + +struct fcram_hash_opt { + u64 header; +}; + +/* EXT=1, FMT=0 */ +struct fcram_hash_ipv4 { + u64 header; + u64 addrs; + u64 ports; + u64 action; +}; + +/* EXT=1, FMT=1 */ +struct fcram_hash_ipv6 { + u64 header; + u64 addrs[4]; + u64 ports; + u64 action; +}; + +#define HASH_TBL_DATA_LOG(IDX) (FFLP + 0x00010UL + (IDX) * 8192UL) +#define HASH_TBL_DATA_LOG_ERR 0x0000000080000000ULL +#define HASH_TBL_DATA_LOG_ADDR 0x000000007fffff00ULL +#define HASH_TBL_DATA_LOG_SYNDROME 0x00000000000000ffULL + +#define RX_DMA_CK_DIV (FZC_DMC + 0x00000UL) +#define RX_DMA_CK_DIV_CNT 0x000000000000ffffULL + +#define DEF_RDC(IDX) (FZC_DMC + 0x00008UL + (IDX) * 0x8UL) +#define DEF_RDC_VAL 0x000000000000001fULL + +#define PT_DRR_WT(IDX) (FZC_DMC + 0x00028UL + (IDX) * 0x8UL) +#define PT_DRR_WT_VAL 0x000000000000ffffULL + +#define PT_DRR_WEIGHT_DEFAULT_10G 0x0400 +#define PT_DRR_WEIGHT_DEFAULT_1G 0x0066 + +#define PT_USE(IDX) (FZC_DMC + 0x00048UL + (IDX) * 0x8UL) +#define PT_USE_CNT 0x00000000000fffffULL + +#define RED_RAN_INIT (FZC_DMC + 0x00068UL) +#define RED_RAN_INIT_OPMODE 0x0000000000010000ULL +#define RED_RAN_INIT_VAL 0x000000000000ffffULL + +#define RX_ADDR_MD (FZC_DMC + 0x00070UL) +#define RX_ADDR_MD_DBG_PT_MUX_SEL 0x000000000000000cULL +#define RX_ADDR_MD_RAM_ACC 0x0000000000000002ULL +#define RX_ADDR_MD_MODE32 0x0000000000000001ULL + +#define RDMC_PRE_PAR_ERR (FZC_DMC + 0x00078UL) +#define RDMC_PRE_PAR_ERR_ERR 0x0000000000008000ULL +#define RDMC_PRE_PAR_ERR_MERR 0x0000000000004000ULL +#define RDMC_PRE_PAR_ERR_ADDR 0x00000000000000ffULL + +#define RDMC_SHA_PAR_ERR (FZC_DMC + 0x00080UL) +#define RDMC_SHA_PAR_ERR_ERR 0x0000000000008000ULL +#define RDMC_SHA_PAR_ERR_MERR 0x0000000000004000ULL +#define RDMC_SHA_PAR_ERR_ADDR 0x00000000000000ffULL + +#define RDMC_MEM_ADDR (FZC_DMC + 0x00088UL) +#define RDMC_MEM_ADDR_PRE_SHAD 0x0000000000000100ULL +#define RDMC_MEM_ADDR_ADDR 0x00000000000000ffULL + +#define RDMC_MEM_DAT0 (FZC_DMC + 0x00090UL) +#define RDMC_MEM_DAT0_DATA 0x00000000ffffffffULL /* bits 31:0 */ + +#define RDMC_MEM_DAT1 (FZC_DMC + 0x00098UL) +#define RDMC_MEM_DAT1_DATA 0x00000000ffffffffULL /* bits 63:32 */ + +#define RDMC_MEM_DAT2 (FZC_DMC + 0x000a0UL) +#define RDMC_MEM_DAT2_DATA 0x00000000ffffffffULL /* bits 95:64 */ + +#define RDMC_MEM_DAT3 (FZC_DMC + 0x000a8UL) +#define RDMC_MEM_DAT3_DATA 0x00000000ffffffffULL /* bits 127:96 */ + +#define RDMC_MEM_DAT4 (FZC_DMC + 0x000b0UL) +#define RDMC_MEM_DAT4_DATA 0x00000000000fffffULL /* bits 147:128 */ + +#define RX_CTL_DAT_FIFO_STAT (FZC_DMC + 0x000b8UL) +#define RX_CTL_DAT_FIFO_STAT_ID_MISMATCH 0x0000000000000100ULL +#define RX_CTL_DAT_FIFO_STAT_ZCP_EOP_ERR 0x00000000000000f0ULL +#define RX_CTL_DAT_FIFO_STAT_IPP_EOP_ERR 0x000000000000000fULL + +#define RX_CTL_DAT_FIFO_MASK (FZC_DMC + 0x000c0UL) +#define RX_CTL_DAT_FIFO_MASK_ID_MISMATCH 0x0000000000000100ULL +#define RX_CTL_DAT_FIFO_MASK_ZCP_EOP_ERR 0x00000000000000f0ULL +#define RX_CTL_DAT_FIFO_MASK_IPP_EOP_ERR 0x000000000000000fULL + +#define RDMC_TRAINING_VECTOR (FZC_DMC + 0x000c8UL) +#define RDMC_TRAINING_VECTOR_TRAINING_VECTOR 0x00000000ffffffffULL + +#define RX_CTL_DAT_FIFO_STAT_DBG (FZC_DMC + 0x000d0UL) +#define RX_CTL_DAT_FIFO_STAT_DBG_ID_MISMATCH 0x0000000000000100ULL +#define RX_CTL_DAT_FIFO_STAT_DBG_ZCP_EOP_ERR 0x00000000000000f0ULL +#define RX_CTL_DAT_FIFO_STAT_DBG_IPP_EOP_ERR 0x000000000000000fULL + +#define RDC_TBL(TBL,SLOT) (FZC_ZCP + 0x10000UL + \ + (TBL) * (8UL * 16UL) + \ + (SLOT) * 8UL) +#define RDC_TBL_RDC 0x000000000000000fULL + +#define RX_LOG_PAGE_VLD(IDX) (FZC_DMC + 0x20000UL + (IDX) * 0x40UL) +#define RX_LOG_PAGE_VLD_FUNC 0x000000000000000cULL +#define RX_LOG_PAGE_VLD_FUNC_SHIFT 2 +#define RX_LOG_PAGE_VLD_PAGE1 0x0000000000000002ULL +#define RX_LOG_PAGE_VLD_PAGE0 0x0000000000000001ULL + +#define RX_LOG_MASK1(IDX) (FZC_DMC + 0x20008UL + (IDX) * 0x40UL) +#define RX_LOG_MASK1_MASK 0x00000000ffffffffULL + +#define RX_LOG_VAL1(IDX) (FZC_DMC + 0x20010UL + (IDX) * 0x40UL) +#define RX_LOG_VAL1_VALUE 0x00000000ffffffffULL + +#define RX_LOG_MASK2(IDX) (FZC_DMC + 0x20018UL + (IDX) * 0x40UL) +#define RX_LOG_MASK2_MASK 0x00000000ffffffffULL + +#define RX_LOG_VAL2(IDX) (FZC_DMC + 0x20020UL + (IDX) * 0x40UL) +#define RX_LOG_VAL2_VALUE 0x00000000ffffffffULL + +#define RX_LOG_PAGE_RELO1(IDX) (FZC_DMC + 0x20028UL + (IDX) * 0x40UL) +#define RX_LOG_PAGE_RELO1_RELO 0x00000000ffffffffULL + +#define RX_LOG_PAGE_RELO2(IDX) (FZC_DMC + 0x20030UL + (IDX) * 0x40UL) +#define RX_LOG_PAGE_RELO2_RELO 0x00000000ffffffffULL + +#define RX_LOG_PAGE_HDL(IDX) (FZC_DMC + 0x20038UL + (IDX) * 0x40UL) +#define RX_LOG_PAGE_HDL_HANDLE 0x00000000000fffffULL + +#define TX_LOG_PAGE_VLD(IDX) (FZC_DMC + 0x40000UL + (IDX) * 0x200UL) +#define TX_LOG_PAGE_VLD_FUNC 0x000000000000000cULL +#define TX_LOG_PAGE_VLD_FUNC_SHIFT 2 +#define TX_LOG_PAGE_VLD_PAGE1 0x0000000000000002ULL +#define TX_LOG_PAGE_VLD_PAGE0 0x0000000000000001ULL + +#define TX_LOG_MASK1(IDX) (FZC_DMC + 0x40008UL + (IDX) * 0x200UL) +#define TX_LOG_MASK1_MASK 0x00000000ffffffffULL + +#define TX_LOG_VAL1(IDX) (FZC_DMC + 0x40010UL + (IDX) * 0x200UL) +#define TX_LOG_VAL1_VALUE 0x00000000ffffffffULL + +#define TX_LOG_MASK2(IDX) (FZC_DMC + 0x40018UL + (IDX) * 0x200UL) +#define TX_LOG_MASK2_MASK 0x00000000ffffffffULL + +#define TX_LOG_VAL2(IDX) (FZC_DMC + 0x40020UL + (IDX) * 0x200UL) +#define TX_LOG_VAL2_VALUE 0x00000000ffffffffULL + +#define TX_LOG_PAGE_RELO1(IDX) (FZC_DMC + 0x40028UL + (IDX) * 0x200UL) +#define TX_LOG_PAGE_RELO1_RELO 0x00000000ffffffffULL + +#define TX_LOG_PAGE_RELO2(IDX) (FZC_DMC + 0x40030UL + (IDX) * 0x200UL) +#define TX_LOG_PAGE_RELO2_RELO 0x00000000ffffffffULL + +#define TX_LOG_PAGE_HDL(IDX) (FZC_DMC + 0x40038UL + (IDX) * 0x200UL) +#define TX_LOG_PAGE_HDL_HANDLE 0x00000000000fffffULL + +#define TX_ADDR_MD (FZC_DMC + 0x45000UL) +#define TX_ADDR_MD_MODE32 0x0000000000000001ULL + +#define RDC_RED_PARA(IDX) (FZC_DMC + 0x30000UL + (IDX) * 0x40UL) +#define RDC_RED_PARA_THRE_SYN 0x00000000fff00000ULL +#define RDC_RED_PARA_THRE_SYN_SHIFT 20 +#define RDC_RED_PARA_WIN_SYN 0x00000000000f0000ULL +#define RDC_RED_PARA_WIN_SYN_SHIFT 16 +#define RDC_RED_PARA_THRE 0x000000000000fff0ULL +#define RDC_RED_PARA_THRE_SHIFT 4 +#define RDC_RED_PARA_WIN 0x000000000000000fULL +#define RDC_RED_PARA_WIN_SHIFT 0 + +#define RED_DIS_CNT(IDX) (FZC_DMC + 0x30008UL + (IDX) * 0x40UL) +#define RED_DIS_CNT_OFLOW 0x0000000000010000ULL +#define RED_DIS_CNT_COUNT 0x000000000000ffffULL + +#define IPP_CFIG (FZC_IPP + 0x00000UL) +#define IPP_CFIG_SOFT_RST 0x0000000080000000ULL +#define IPP_CFIG_IP_MAX_PKT 0x0000000001ffff00ULL +#define IPP_CFIG_IP_MAX_PKT_SHIFT 8 +#define IPP_CFIG_FFLP_CS_PIO_W 0x0000000000000080ULL +#define IPP_CFIG_PFIFO_PIO_W 0x0000000000000040ULL +#define IPP_CFIG_DFIFO_PIO_W 0x0000000000000020ULL +#define IPP_CFIG_CKSUM_EN 0x0000000000000010ULL +#define IPP_CFIG_DROP_BAD_CRC 0x0000000000000008ULL +#define IPP_CFIG_DFIFO_ECC_EN 0x0000000000000004ULL +#define IPP_CFIG_DEBUG_BUS_OUT_EN 0x0000000000000002ULL +#define IPP_CFIG_IPP_ENABLE 0x0000000000000001ULL + +#define IPP_PKT_DIS (FZC_IPP + 0x00020UL) +#define IPP_PKT_DIS_COUNT 0x0000000000003fffULL + +#define IPP_BAD_CS_CNT (FZC_IPP + 0x00028UL) +#define IPP_BAD_CS_CNT_COUNT 0x0000000000003fffULL + +#define IPP_ECC (FZC_IPP + 0x00030UL) +#define IPP_ECC_COUNT 0x00000000000000ffULL + +#define IPP_INT_STAT (FZC_IPP + 0x00040UL) +#define IPP_INT_STAT_SOP_MISS 0x0000000080000000ULL +#define IPP_INT_STAT_EOP_MISS 0x0000000040000000ULL +#define IPP_INT_STAT_DFIFO_UE 0x0000000030000000ULL +#define IPP_INT_STAT_DFIFO_CE 0x000000000c000000ULL +#define IPP_INT_STAT_DFIFO_ECC 0x0000000003000000ULL +#define IPP_INT_STAT_DFIFO_ECC_IDX 0x00000000007ff000ULL +#define IPP_INT_STAT_PFIFO_PERR 0x0000000000000800ULL +#define IPP_INT_STAT_ECC_ERR_MAX 0x0000000000000400ULL +#define IPP_INT_STAT_PFIFO_ERR_IDX 0x00000000000003f0ULL +#define IPP_INT_STAT_PFIFO_OVER 0x0000000000000008ULL +#define IPP_INT_STAT_PFIFO_UND 0x0000000000000004ULL +#define IPP_INT_STAT_BAD_CS_MX 0x0000000000000002ULL +#define IPP_INT_STAT_PKT_DIS_MX 0x0000000000000001ULL +#define IPP_INT_STAT_ALL 0x00000000ff7fffffULL + +#define IPP_MSK (FZC_IPP + 0x00048UL) +#define IPP_MSK_ECC_ERR_MX 0x0000000000000080ULL +#define IPP_MSK_DFIFO_EOP_SOP 0x0000000000000040ULL +#define IPP_MSK_DFIFO_UC 0x0000000000000020ULL +#define IPP_MSK_PFIFO_PAR 0x0000000000000010ULL +#define IPP_MSK_PFIFO_OVER 0x0000000000000008ULL +#define IPP_MSK_PFIFO_UND 0x0000000000000004ULL +#define IPP_MSK_BAD_CS 0x0000000000000002ULL +#define IPP_MSK_PKT_DIS_CNT 0x0000000000000001ULL +#define IPP_MSK_ALL 0x00000000000000ffULL + +#define IPP_PFIFO_RD0 (FZC_IPP + 0x00060UL) +#define IPP_PFIFO_RD0_DATA 0x00000000ffffffffULL /* bits 31:0 */ + +#define IPP_PFIFO_RD1 (FZC_IPP + 0x00068UL) +#define IPP_PFIFO_RD1_DATA 0x00000000ffffffffULL /* bits 63:32 */ + +#define IPP_PFIFO_RD2 (FZC_IPP + 0x00070UL) +#define IPP_PFIFO_RD2_DATA 0x00000000ffffffffULL /* bits 95:64 */ + +#define IPP_PFIFO_RD3 (FZC_IPP + 0x00078UL) +#define IPP_PFIFO_RD3_DATA 0x00000000ffffffffULL /* bits 127:96 */ + +#define IPP_PFIFO_RD4 (FZC_IPP + 0x00080UL) +#define IPP_PFIFO_RD4_DATA 0x00000000ffffffffULL /* bits 145:128 */ + +#define IPP_PFIFO_WR0 (FZC_IPP + 0x00088UL) +#define IPP_PFIFO_WR0_DATA 0x00000000ffffffffULL /* bits 31:0 */ + +#define IPP_PFIFO_WR1 (FZC_IPP + 0x00090UL) +#define IPP_PFIFO_WR1_DATA 0x00000000ffffffffULL /* bits 63:32 */ + +#define IPP_PFIFO_WR2 (FZC_IPP + 0x00098UL) +#define IPP_PFIFO_WR2_DATA 0x00000000ffffffffULL /* bits 95:64 */ + +#define IPP_PFIFO_WR3 (FZC_IPP + 0x000a0UL) +#define IPP_PFIFO_WR3_DATA 0x00000000ffffffffULL /* bits 127:96 */ + +#define IPP_PFIFO_WR4 (FZC_IPP + 0x000a8UL) +#define IPP_PFIFO_WR4_DATA 0x00000000ffffffffULL /* bits 145:128 */ + +#define IPP_PFIFO_RD_PTR (FZC_IPP + 0x000b0UL) +#define IPP_PFIFO_RD_PTR_PTR 0x000000000000003fULL + +#define IPP_PFIFO_WR_PTR (FZC_IPP + 0x000b8UL) +#define IPP_PFIFO_WR_PTR_PTR 0x000000000000007fULL + +#define IPP_DFIFO_RD0 (FZC_IPP + 0x000c0UL) +#define IPP_DFIFO_RD0_DATA 0x00000000ffffffffULL /* bits 31:0 */ + +#define IPP_DFIFO_RD1 (FZC_IPP + 0x000c8UL) +#define IPP_DFIFO_RD1_DATA 0x00000000ffffffffULL /* bits 63:32 */ + +#define IPP_DFIFO_RD2 (FZC_IPP + 0x000d0UL) +#define IPP_DFIFO_RD2_DATA 0x00000000ffffffffULL /* bits 95:64 */ + +#define IPP_DFIFO_RD3 (FZC_IPP + 0x000d8UL) +#define IPP_DFIFO_RD3_DATA 0x00000000ffffffffULL /* bits 127:96 */ + +#define IPP_DFIFO_RD4 (FZC_IPP + 0x000e0UL) +#define IPP_DFIFO_RD4_DATA 0x00000000ffffffffULL /* bits 145:128 */ + +#define IPP_DFIFO_WR0 (FZC_IPP + 0x000e8UL) +#define IPP_DFIFO_WR0_DATA 0x00000000ffffffffULL /* bits 31:0 */ + +#define IPP_DFIFO_WR1 (FZC_IPP + 0x000f0UL) +#define IPP_DFIFO_WR1_DATA 0x00000000ffffffffULL /* bits 63:32 */ + +#define IPP_DFIFO_WR2 (FZC_IPP + 0x000f8UL) +#define IPP_DFIFO_WR2_DATA 0x00000000ffffffffULL /* bits 95:64 */ + +#define IPP_DFIFO_WR3 (FZC_IPP + 0x00100UL) +#define IPP_DFIFO_WR3_DATA 0x00000000ffffffffULL /* bits 127:96 */ + +#define IPP_DFIFO_WR4 (FZC_IPP + 0x00108UL) +#define IPP_DFIFO_WR4_DATA 0x00000000ffffffffULL /* bits 145:128 */ + +#define IPP_DFIFO_RD_PTR (FZC_IPP + 0x00110UL) +#define IPP_DFIFO_RD_PTR_PTR 0x0000000000000fffULL + +#define IPP_DFIFO_WR_PTR (FZC_IPP + 0x00118UL) +#define IPP_DFIFO_WR_PTR_PTR 0x0000000000000fffULL + +#define IPP_SM (FZC_IPP + 0x00120UL) +#define IPP_SM_SM 0x00000000ffffffffULL + +#define IPP_CS_STAT (FZC_IPP + 0x00128UL) +#define IPP_CS_STAT_BCYC_CNT 0x00000000ff000000ULL +#define IPP_CS_STAT_IP_LEN 0x0000000000fff000ULL +#define IPP_CS_STAT_CS_FAIL 0x0000000000000800ULL +#define IPP_CS_STAT_TERM 0x0000000000000400ULL +#define IPP_CS_STAT_BAD_NUM 0x0000000000000200ULL +#define IPP_CS_STAT_CS_STATE 0x00000000000001ffULL + +#define IPP_FFLP_CS_INFO (FZC_IPP + 0x00130UL) +#define IPP_FFLP_CS_INFO_PKT_ID 0x0000000000003c00ULL +#define IPP_FFLP_CS_INFO_L4_PROTO 0x0000000000000300ULL +#define IPP_FFLP_CS_INFO_V4_HD_LEN 0x00000000000000f0ULL +#define IPP_FFLP_CS_INFO_L3_VER 0x000000000000000cULL +#define IPP_FFLP_CS_INFO_L2_OP 0x0000000000000003ULL + +#define IPP_DBG_SEL (FZC_IPP + 0x00138UL) +#define IPP_DBG_SEL_SEL 0x000000000000000fULL + +#define IPP_DFIFO_ECC_SYND (FZC_IPP + 0x00140UL) +#define IPP_DFIFO_ECC_SYND_SYND 0x000000000000ffffULL + +#define IPP_DFIFO_EOP_RD_PTR (FZC_IPP + 0x00148UL) +#define IPP_DFIFO_EOP_RD_PTR_PTR 0x0000000000000fffULL + +#define IPP_ECC_CTL (FZC_IPP + 0x00150UL) +#define IPP_ECC_CTL_DIS_DBL 0x0000000080000000ULL +#define IPP_ECC_CTL_COR_DBL 0x0000000000020000ULL +#define IPP_ECC_CTL_COR_SNG 0x0000000000010000ULL +#define IPP_ECC_CTL_COR_ALL 0x0000000000000400ULL +#define IPP_ECC_CTL_COR_1 0x0000000000000100ULL +#define IPP_ECC_CTL_COR_LST 0x0000000000000004ULL +#define IPP_ECC_CTL_COR_SND 0x0000000000000002ULL +#define IPP_ECC_CTL_COR_FSR 0x0000000000000001ULL + +#define NIU_DFIFO_ENTRIES 1024 +#define ATLAS_P0_P1_DFIFO_ENTRIES 2048 +#define ATLAS_P2_P3_DFIFO_ENTRIES 1024 + +#define ZCP_CFIG (FZC_ZCP + 0x00000UL) +#define ZCP_CFIG_ZCP_32BIT_MODE 0x0000000001000000ULL +#define ZCP_CFIG_ZCP_DEBUG_SEL 0x0000000000ff0000ULL +#define ZCP_CFIG_DMA_TH 0x000000000000ffe0ULL +#define ZCP_CFIG_ECC_CHK_DIS 0x0000000000000010ULL +#define ZCP_CFIG_PAR_CHK_DIS 0x0000000000000008ULL +#define ZCP_CFIG_DIS_BUFF_RSP_IF 0x0000000000000004ULL +#define ZCP_CFIG_DIS_BUFF_REQ_IF 0x0000000000000002ULL +#define ZCP_CFIG_ZC_ENABLE 0x0000000000000001ULL + +#define ZCP_INT_STAT (FZC_ZCP + 0x00008UL) +#define ZCP_INT_STAT_RRFIFO_UNDERRUN 0x0000000000008000ULL +#define ZCP_INT_STAT_RRFIFO_OVERRUN 0x0000000000004000ULL +#define ZCP_INT_STAT_RSPFIFO_UNCOR_ERR 0x0000000000001000ULL +#define ZCP_INT_STAT_BUFFER_OVERFLOW 0x0000000000000800ULL +#define ZCP_INT_STAT_STAT_TBL_PERR 0x0000000000000400ULL +#define ZCP_INT_STAT_DYN_TBL_PERR 0x0000000000000200ULL +#define ZCP_INT_STAT_BUF_TBL_PERR 0x0000000000000100ULL +#define ZCP_INT_STAT_TT_PROGRAM_ERR 0x0000000000000080ULL +#define ZCP_INT_STAT_RSP_TT_INDEX_ERR 0x0000000000000040ULL +#define ZCP_INT_STAT_SLV_TT_INDEX_ERR 0x0000000000000020ULL +#define ZCP_INT_STAT_ZCP_TT_INDEX_ERR 0x0000000000000010ULL +#define ZCP_INT_STAT_CFIFO_ECC3 0x0000000000000008ULL +#define ZCP_INT_STAT_CFIFO_ECC2 0x0000000000000004ULL +#define ZCP_INT_STAT_CFIFO_ECC1 0x0000000000000002ULL +#define ZCP_INT_STAT_CFIFO_ECC0 0x0000000000000001ULL +#define ZCP_INT_STAT_ALL 0x000000000000ffffULL + +#define ZCP_INT_MASK (FZC_ZCP + 0x00010UL) +#define ZCP_INT_MASK_RRFIFO_UNDERRUN 0x0000000000008000ULL +#define ZCP_INT_MASK_RRFIFO_OVERRUN 0x0000000000004000ULL +#define ZCP_INT_MASK_LOJ 0x0000000000002000ULL +#define ZCP_INT_MASK_RSPFIFO_UNCOR_ERR 0x0000000000001000ULL +#define ZCP_INT_MASK_BUFFER_OVERFLOW 0x0000000000000800ULL +#define ZCP_INT_MASK_STAT_TBL_PERR 0x0000000000000400ULL +#define ZCP_INT_MASK_DYN_TBL_PERR 0x0000000000000200ULL +#define ZCP_INT_MASK_BUF_TBL_PERR 0x0000000000000100ULL +#define ZCP_INT_MASK_TT_PROGRAM_ERR 0x0000000000000080ULL +#define ZCP_INT_MASK_RSP_TT_INDEX_ERR 0x0000000000000040ULL +#define ZCP_INT_MASK_SLV_TT_INDEX_ERR 0x0000000000000020ULL +#define ZCP_INT_MASK_ZCP_TT_INDEX_ERR 0x0000000000000010ULL +#define ZCP_INT_MASK_CFIFO_ECC3 0x0000000000000008ULL +#define ZCP_INT_MASK_CFIFO_ECC2 0x0000000000000004ULL +#define ZCP_INT_MASK_CFIFO_ECC1 0x0000000000000002ULL +#define ZCP_INT_MASK_CFIFO_ECC0 0x0000000000000001ULL +#define ZCP_INT_MASK_ALL 0x000000000000ffffULL + +#define BAM4BUF (FZC_ZCP + 0x00018UL) +#define BAM4BUF_LOJ 0x0000000080000000ULL +#define BAM4BUF_EN_CK 0x0000000040000000ULL +#define BAM4BUF_IDX_END0 0x000000003ff00000ULL +#define BAM4BUF_IDX_ST0 0x00000000000ffc00ULL +#define BAM4BUF_OFFSET0 0x00000000000003ffULL + +#define BAM8BUF (FZC_ZCP + 0x00020UL) +#define BAM8BUF_LOJ 0x0000000080000000ULL +#define BAM8BUF_EN_CK 0x0000000040000000ULL +#define BAM8BUF_IDX_END1 0x000000003ff00000ULL +#define BAM8BUF_IDX_ST1 0x00000000000ffc00ULL +#define BAM8BUF_OFFSET1 0x00000000000003ffULL + +#define BAM16BUF (FZC_ZCP + 0x00028UL) +#define BAM16BUF_LOJ 0x0000000080000000ULL +#define BAM16BUF_EN_CK 0x0000000040000000ULL +#define BAM16BUF_IDX_END2 0x000000003ff00000ULL +#define BAM16BUF_IDX_ST2 0x00000000000ffc00ULL +#define BAM16BUF_OFFSET2 0x00000000000003ffULL + +#define BAM32BUF (FZC_ZCP + 0x00030UL) +#define BAM32BUF_LOJ 0x0000000080000000ULL +#define BAM32BUF_EN_CK 0x0000000040000000ULL +#define BAM32BUF_IDX_END3 0x000000003ff00000ULL +#define BAM32BUF_IDX_ST3 0x00000000000ffc00ULL +#define BAM32BUF_OFFSET3 0x00000000000003ffULL + +#define DST4BUF (FZC_ZCP + 0x00038UL) +#define DST4BUF_DS_OFFSET0 0x00000000000003ffULL + +#define DST8BUF (FZC_ZCP + 0x00040UL) +#define DST8BUF_DS_OFFSET1 0x00000000000003ffULL + +#define DST16BUF (FZC_ZCP + 0x00048UL) +#define DST16BUF_DS_OFFSET2 0x00000000000003ffULL + +#define DST32BUF (FZC_ZCP + 0x00050UL) +#define DST32BUF_DS_OFFSET3 0x00000000000003ffULL + +#define ZCP_RAM_DATA0 (FZC_ZCP + 0x00058UL) +#define ZCP_RAM_DATA0_DAT0 0x00000000ffffffffULL + +#define ZCP_RAM_DATA1 (FZC_ZCP + 0x00060UL) +#define ZCP_RAM_DAT10_DAT1 0x00000000ffffffffULL + +#define ZCP_RAM_DATA2 (FZC_ZCP + 0x00068UL) +#define ZCP_RAM_DATA2_DAT2 0x00000000ffffffffULL + +#define ZCP_RAM_DATA3 (FZC_ZCP + 0x00070UL) +#define ZCP_RAM_DATA3_DAT3 0x00000000ffffffffULL + +#define ZCP_RAM_DATA4 (FZC_ZCP + 0x00078UL) +#define ZCP_RAM_DATA4_DAT4 0x00000000000000ffULL + +#define ZCP_RAM_BE (FZC_ZCP + 0x00080UL) +#define ZCP_RAM_BE_VAL 0x000000000001ffffULL + +#define ZCP_RAM_ACC (FZC_ZCP + 0x00088UL) +#define ZCP_RAM_ACC_BUSY 0x0000000080000000ULL +#define ZCP_RAM_ACC_READ 0x0000000040000000ULL +#define ZCP_RAM_ACC_WRITE 0x0000000000000000ULL +#define ZCP_RAM_ACC_LOJ 0x0000000020000000ULL +#define ZCP_RAM_ACC_ZFCID 0x000000001ffe0000ULL +#define ZCP_RAM_ACC_ZFCID_SHIFT 17 +#define ZCP_RAM_ACC_RAM_SEL 0x000000000001f000ULL +#define ZCP_RAM_ACC_RAM_SEL_SHIFT 12 +#define ZCP_RAM_ACC_CFIFOADDR 0x0000000000000fffULL +#define ZCP_RAM_ACC_CFIFOADDR_SHIFT 0 + +#define ZCP_RAM_SEL_BAM(INDEX) (0x00 + (INDEX)) +#define ZCP_RAM_SEL_TT_STATIC 0x08 +#define ZCP_RAM_SEL_TT_DYNAMIC 0x09 +#define ZCP_RAM_SEL_CFIFO(PORT) (0x10 + (PORT)) + +#define NIU_CFIFO_ENTRIES 1024 +#define ATLAS_P0_P1_CFIFO_ENTRIES 2048 +#define ATLAS_P2_P3_CFIFO_ENTRIES 1024 + +#define CHK_BIT_DATA (FZC_ZCP + 0x00090UL) +#define CHK_BIT_DATA_DATA 0x000000000000ffffULL + +#define RESET_CFIFO (FZC_ZCP + 0x00098UL) +#define RESET_CFIFO_RST(PORT) (0x1 << (PORT)) + +#define CFIFO_ECC(PORT) (FZC_ZCP + 0x000a0UL + (PORT) * 8UL) +#define CFIFO_ECC_DIS_DBLBIT_ERR 0x0000000080000000ULL +#define CFIFO_ECC_DBLBIT_ERR 0x0000000000020000ULL +#define CFIFO_ECC_SINGLEBIT_ERR 0x0000000000010000ULL +#define CFIFO_ECC_ALL_PKT 0x0000000000000400ULL +#define CFIFO_ECC_LAST_LINE 0x0000000000000004ULL +#define CFIFO_ECC_2ND_LINE 0x0000000000000002ULL +#define CFIFO_ECC_1ST_LINE 0x0000000000000001ULL + +#define ZCP_TRAINING_VECTOR (FZC_ZCP + 0x000c0UL) +#define ZCP_TRAINING_VECTOR_VECTOR 0x00000000ffffffffULL + +#define ZCP_STATE_MACHINE (FZC_ZCP + 0x000c8UL) +#define ZCP_STATE_MACHINE_SM 0x00000000ffffffffULL + +/* Same bits as ZCP_INT_STAT */ +#define ZCP_INT_STAT_TEST (FZC_ZCP + 0x00108UL) + +#define RXDMA_CFIG1(IDX) (DMC + 0x00000UL + (IDX) * 0x200UL) +#define RXDMA_CFIG1_EN 0x0000000080000000ULL +#define RXDMA_CFIG1_RST 0x0000000040000000ULL +#define RXDMA_CFIG1_QST 0x0000000020000000ULL +#define RXDMA_CFIG1_MBADDR_H 0x0000000000000fffULL /* mboxaddr 43:32 */ + +#define RXDMA_CFIG2(IDX) (DMC + 0x00008UL + (IDX) * 0x200UL) +#define RXDMA_CFIG2_MBADDR_L 0x00000000ffffffc0ULL /* mboxaddr 31:6 */ +#define RXDMA_CFIG2_OFFSET 0x0000000000000006ULL +#define RXDMA_CFIG2_OFFSET_SHIFT 1 +#define RXDMA_CFIG2_FULL_HDR 0x0000000000000001ULL + +#define RBR_CFIG_A(IDX) (DMC + 0x00010UL + (IDX) * 0x200UL) +#define RBR_CFIG_A_LEN 0xffff000000000000ULL +#define RBR_CFIG_A_LEN_SHIFT 48 +#define RBR_CFIG_A_STADDR_BASE 0x00000ffffffc0000ULL +#define RBR_CFIG_A_STADDR 0x000000000003ffc0ULL + +#define RBR_CFIG_B(IDX) (DMC + 0x00018UL + (IDX) * 0x200UL) +#define RBR_CFIG_B_BLKSIZE 0x0000000003000000ULL +#define RBR_CFIG_B_BLKSIZE_SHIFT 24 +#define RBR_CFIG_B_VLD2 0x0000000000800000ULL +#define RBR_CFIG_B_BUFSZ2 0x0000000000030000ULL +#define RBR_CFIG_B_BUFSZ2_SHIFT 16 +#define RBR_CFIG_B_VLD1 0x0000000000008000ULL +#define RBR_CFIG_B_BUFSZ1 0x0000000000000300ULL +#define RBR_CFIG_B_BUFSZ1_SHIFT 8 +#define RBR_CFIG_B_VLD0 0x0000000000000080ULL +#define RBR_CFIG_B_BUFSZ0 0x0000000000000003ULL +#define RBR_CFIG_B_BUFSZ0_SHIFT 0 + +#define RBR_BLKSIZE_4K 0x0 +#define RBR_BLKSIZE_8K 0x1 +#define RBR_BLKSIZE_16K 0x2 +#define RBR_BLKSIZE_32K 0x3 +#define RBR_BUFSZ2_2K 0x0 +#define RBR_BUFSZ2_4K 0x1 +#define RBR_BUFSZ2_8K 0x2 +#define RBR_BUFSZ2_16K 0x3 +#define RBR_BUFSZ1_1K 0x0 +#define RBR_BUFSZ1_2K 0x1 +#define RBR_BUFSZ1_4K 0x2 +#define RBR_BUFSZ1_8K 0x3 +#define RBR_BUFSZ0_256 0x0 +#define RBR_BUFSZ0_512 0x1 +#define RBR_BUFSZ0_1K 0x2 +#define RBR_BUFSZ0_2K 0x3 + +#define RBR_KICK(IDX) (DMC + 0x00020UL + (IDX) * 0x200UL) +#define RBR_KICK_BKADD 0x000000000000ffffULL + +#define RBR_STAT(IDX) (DMC + 0x00028UL + (IDX) * 0x200UL) +#define RBR_STAT_QLEN 0x000000000000ffffULL + +#define RBR_HDH(IDX) (DMC + 0x00030UL + (IDX) * 0x200UL) +#define RBR_HDH_HEAD_H 0x0000000000000fffULL + +#define RBR_HDL(IDX) (DMC + 0x00038UL + (IDX) * 0x200UL) +#define RBR_HDL_HEAD_L 0x00000000fffffffcULL + +#define RCRCFIG_A(IDX) (DMC + 0x00040UL + (IDX) * 0x200UL) +#define RCRCFIG_A_LEN 0xffff000000000000ULL +#define RCRCFIG_A_LEN_SHIFT 48 +#define RCRCFIG_A_STADDR_BASE 0x00000ffffff80000ULL +#define RCRCFIG_A_STADDR 0x000000000007ffc0ULL + +#define RCRCFIG_B(IDX) (DMC + 0x00048UL + (IDX) * 0x200UL) +#define RCRCFIG_B_PTHRES 0x00000000ffff0000ULL +#define RCRCFIG_B_PTHRES_SHIFT 16 +#define RCRCFIG_B_ENTOUT 0x0000000000008000ULL +#define RCRCFIG_B_TIMEOUT 0x000000000000003fULL +#define RCRCFIG_B_TIMEOUT_SHIFT 0 + +#define RCRSTAT_A(IDX) (DMC + 0x00050UL + (IDX) * 0x200UL) +#define RCRSTAT_A_QLEN 0x000000000000ffffULL + +#define RCRSTAT_B(IDX) (DMC + 0x00058UL + (IDX) * 0x200UL) +#define RCRSTAT_B_TIPTR_H 0x0000000000000fffULL + +#define RCRSTAT_C(IDX) (DMC + 0x00060UL + (IDX) * 0x200UL) +#define RCRSTAT_C_TIPTR_L 0x00000000fffffff8ULL + +#define RX_DMA_CTL_STAT(IDX) (DMC + 0x00070UL + (IDX) * 0x200UL) +#define RX_DMA_CTL_STAT_RBR_TMOUT 0x0020000000000000ULL +#define RX_DMA_CTL_STAT_RSP_CNT_ERR 0x0010000000000000ULL +#define RX_DMA_CTL_STAT_BYTE_EN_BUS 0x0008000000000000ULL +#define RX_DMA_CTL_STAT_RSP_DAT_ERR 0x0004000000000000ULL +#define RX_DMA_CTL_STAT_RCR_ACK_ERR 0x0002000000000000ULL +#define RX_DMA_CTL_STAT_DC_FIFO_ERR 0x0001000000000000ULL +#define RX_DMA_CTL_STAT_MEX 0x0000800000000000ULL +#define RX_DMA_CTL_STAT_RCRTHRES 0x0000400000000000ULL +#define RX_DMA_CTL_STAT_RCRTO 0x0000200000000000ULL +#define RX_DMA_CTL_STAT_RCR_SHA_PAR 0x0000100000000000ULL +#define RX_DMA_CTL_STAT_RBR_PRE_PAR 0x0000080000000000ULL +#define RX_DMA_CTL_STAT_PORT_DROP_PKT 0x0000040000000000ULL +#define RX_DMA_CTL_STAT_WRED_DROP 0x0000020000000000ULL +#define RX_DMA_CTL_STAT_RBR_PRE_EMTY 0x0000010000000000ULL +#define RX_DMA_CTL_STAT_RCRSHADOW_FULL 0x0000008000000000ULL +#define RX_DMA_CTL_STAT_CONFIG_ERR 0x0000004000000000ULL +#define RX_DMA_CTL_STAT_RCRINCON 0x0000002000000000ULL +#define RX_DMA_CTL_STAT_RCRFULL 0x0000001000000000ULL +#define RX_DMA_CTL_STAT_RBR_EMPTY 0x0000000800000000ULL +#define RX_DMA_CTL_STAT_RBRFULL 0x0000000400000000ULL +#define RX_DMA_CTL_STAT_RBRLOGPAGE 0x0000000200000000ULL +#define RX_DMA_CTL_STAT_CFIGLOGPAGE 0x0000000100000000ULL +#define RX_DMA_CTL_STAT_PTRREAD 0x00000000ffff0000ULL +#define RX_DMA_CTL_STAT_PTRREAD_SHIFT 16 +#define RX_DMA_CTL_STAT_PKTREAD 0x000000000000ffffULL +#define RX_DMA_CTL_STAT_PKTREAD_SHIFT 0 + +#define RX_DMA_CTL_STAT_CHAN_FATAL (RX_DMA_CTL_STAT_RBR_TMOUT | \ + RX_DMA_CTL_STAT_RSP_CNT_ERR | \ + RX_DMA_CTL_STAT_BYTE_EN_BUS | \ + RX_DMA_CTL_STAT_RSP_DAT_ERR | \ + RX_DMA_CTL_STAT_RCR_ACK_ERR | \ + RX_DMA_CTL_STAT_RCR_SHA_PAR | \ + RX_DMA_CTL_STAT_RBR_PRE_PAR | \ + RX_DMA_CTL_STAT_CONFIG_ERR | \ + RX_DMA_CTL_STAT_RCRINCON | \ + RX_DMA_CTL_STAT_RCRFULL | \ + RX_DMA_CTL_STAT_RBRFULL | \ + RX_DMA_CTL_STAT_RBRLOGPAGE | \ + RX_DMA_CTL_STAT_CFIGLOGPAGE) + +#define RX_DMA_CTL_STAT_PORT_FATAL (RX_DMA_CTL_STAT_DC_FIFO_ERR) + +#define RX_DMA_CTL_WRITE_CLEAR_ERRS (RX_DMA_CTL_STAT_RBR_EMPTY | \ + RX_DMA_CTL_STAT_RCRSHADOW_FULL | \ + RX_DMA_CTL_STAT_RBR_PRE_EMTY | \ + RX_DMA_CTL_STAT_WRED_DROP | \ + RX_DMA_CTL_STAT_PORT_DROP_PKT | \ + RX_DMA_CTL_STAT_RCRTO | \ + RX_DMA_CTL_STAT_RCRTHRES | \ + RX_DMA_CTL_STAT_DC_FIFO_ERR) + +#define RCR_FLSH(IDX) (DMC + 0x00078UL + (IDX) * 0x200UL) +#define RCR_FLSH_FLSH 0x0000000000000001ULL + +#define RXMISC(IDX) (DMC + 0x00090UL + (IDX) * 0x200UL) +#define RXMISC_OFLOW 0x0000000000010000ULL +#define RXMISC_COUNT 0x000000000000ffffULL + +#define RX_DMA_CTL_STAT_DBG(IDX) (DMC + 0x00098UL + (IDX) * 0x200UL) +#define RX_DMA_CTL_STAT_DBG_RBR_TMOUT 0x0020000000000000ULL +#define RX_DMA_CTL_STAT_DBG_RSP_CNT_ERR 0x0010000000000000ULL +#define RX_DMA_CTL_STAT_DBG_BYTE_EN_BUS 0x0008000000000000ULL +#define RX_DMA_CTL_STAT_DBG_RSP_DAT_ERR 0x0004000000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCR_ACK_ERR 0x0002000000000000ULL +#define RX_DMA_CTL_STAT_DBG_DC_FIFO_ERR 0x0001000000000000ULL +#define RX_DMA_CTL_STAT_DBG_MEX 0x0000800000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCRTHRES 0x0000400000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCRTO 0x0000200000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCR_SHA_PAR 0x0000100000000000ULL +#define RX_DMA_CTL_STAT_DBG_RBR_PRE_PAR 0x0000080000000000ULL +#define RX_DMA_CTL_STAT_DBG_PORT_DROP_PKT 0x0000040000000000ULL +#define RX_DMA_CTL_STAT_DBG_WRED_DROP 0x0000020000000000ULL +#define RX_DMA_CTL_STAT_DBG_RBR_PRE_EMTY 0x0000010000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCRSHADOW_FULL 0x0000008000000000ULL +#define RX_DMA_CTL_STAT_DBG_CONFIG_ERR 0x0000004000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCRINCON 0x0000002000000000ULL +#define RX_DMA_CTL_STAT_DBG_RCRFULL 0x0000001000000000ULL +#define RX_DMA_CTL_STAT_DBG_RBR_EMPTY 0x0000000800000000ULL +#define RX_DMA_CTL_STAT_DBG_RBRFULL 0x0000000400000000ULL +#define RX_DMA_CTL_STAT_DBG_RBRLOGPAGE 0x0000000200000000ULL +#define RX_DMA_CTL_STAT_DBG_CFIGLOGPAGE 0x0000000100000000ULL +#define RX_DMA_CTL_STAT_DBG_PTRREAD 0x00000000ffff0000ULL +#define RX_DMA_CTL_STAT_DBG_PKTREAD 0x000000000000ffffULL + +#define RX_DMA_ENT_MSK(IDX) (DMC + 0x00068UL + (IDX) * 0x200UL) +#define RX_DMA_ENT_MSK_RBR_TMOUT 0x0000000000200000ULL +#define RX_DMA_ENT_MSK_RSP_CNT_ERR 0x0000000000100000ULL +#define RX_DMA_ENT_MSK_BYTE_EN_BUS 0x0000000000080000ULL +#define RX_DMA_ENT_MSK_RSP_DAT_ERR 0x0000000000040000ULL +#define RX_DMA_ENT_MSK_RCR_ACK_ERR 0x0000000000020000ULL +#define RX_DMA_ENT_MSK_DC_FIFO_ERR 0x0000000000010000ULL +#define RX_DMA_ENT_MSK_RCRTHRES 0x0000000000004000ULL +#define RX_DMA_ENT_MSK_RCRTO 0x0000000000002000ULL +#define RX_DMA_ENT_MSK_RCR_SHA_PAR 0x0000000000001000ULL +#define RX_DMA_ENT_MSK_RBR_PRE_PAR 0x0000000000000800ULL +#define RX_DMA_ENT_MSK_PORT_DROP_PKT 0x0000000000000400ULL +#define RX_DMA_ENT_MSK_WRED_DROP 0x0000000000000200ULL +#define RX_DMA_ENT_MSK_RBR_PRE_EMTY 0x0000000000000100ULL +#define RX_DMA_ENT_MSK_RCR_SHADOW_FULL 0x0000000000000080ULL +#define RX_DMA_ENT_MSK_CONFIG_ERR 0x0000000000000040ULL +#define RX_DMA_ENT_MSK_RCRINCON 0x0000000000000020ULL +#define RX_DMA_ENT_MSK_RCRFULL 0x0000000000000010ULL +#define RX_DMA_ENT_MSK_RBR_EMPTY 0x0000000000000008ULL +#define RX_DMA_ENT_MSK_RBRFULL 0x0000000000000004ULL +#define RX_DMA_ENT_MSK_RBRLOGPAGE 0x0000000000000002ULL +#define RX_DMA_ENT_MSK_CFIGLOGPAGE 0x0000000000000001ULL +#define RX_DMA_ENT_MSK_ALL 0x00000000003f7fffULL + +#define TX_RNG_CFIG(IDX) (DMC + 0x40000UL + (IDX) * 0x200UL) +#define TX_RNG_CFIG_LEN 0x1fff000000000000ULL +#define TX_RNG_CFIG_LEN_SHIFT 48 +#define TX_RNG_CFIG_STADDR_BASE 0x00000ffffff80000ULL +#define TX_RNG_CFIG_STADDR 0x000000000007ffc0ULL + +#define TX_RING_HDL(IDX) (DMC + 0x40010UL + (IDX) * 0x200UL) +#define TX_RING_HDL_WRAP 0x0000000000080000ULL +#define TX_RING_HDL_HEAD 0x000000000007fff8ULL +#define TX_RING_HDL_HEAD_SHIFT 3 + +#define TX_RING_KICK(IDX) (DMC + 0x40018UL + (IDX) * 0x200UL) +#define TX_RING_KICK_WRAP 0x0000000000080000ULL +#define TX_RING_KICK_TAIL 0x000000000007fff8ULL + +#define TX_ENT_MSK(IDX) (DMC + 0x40020UL + (IDX) * 0x200UL) +#define TX_ENT_MSK_MK 0x0000000000008000ULL +#define TX_ENT_MSK_MBOX_ERR 0x0000000000000080ULL +#define TX_ENT_MSK_PKT_SIZE_ERR 0x0000000000000040ULL +#define TX_ENT_MSK_TX_RING_OFLOW 0x0000000000000020ULL +#define TX_ENT_MSK_PREF_BUF_ECC_ERR 0x0000000000000010ULL +#define TX_ENT_MSK_NACK_PREF 0x0000000000000008ULL +#define TX_ENT_MSK_NACK_PKT_RD 0x0000000000000004ULL +#define TX_ENT_MSK_CONF_PART_ERR 0x0000000000000002ULL +#define TX_ENT_MSK_PKT_PRT_ERR 0x0000000000000001ULL + +#define TX_CS(IDX) (DMC + 0x40028UL + (IDX)*0x200UL) +#define TX_CS_PKT_CNT 0x0fff000000000000ULL +#define TX_CS_PKT_CNT_SHIFT 48 +#define TX_CS_LASTMARK 0x00000fff00000000ULL +#define TX_CS_LASTMARK_SHIFT 32 +#define TX_CS_RST 0x0000000080000000ULL +#define TX_CS_RST_STATE 0x0000000040000000ULL +#define TX_CS_MB 0x0000000020000000ULL +#define TX_CS_STOP_N_GO 0x0000000010000000ULL +#define TX_CS_SNG_STATE 0x0000000008000000ULL +#define TX_CS_MK 0x0000000000008000ULL +#define TX_CS_MMK 0x0000000000004000ULL +#define TX_CS_MBOX_ERR 0x0000000000000080ULL +#define TX_CS_PKT_SIZE_ERR 0x0000000000000040ULL +#define TX_CS_TX_RING_OFLOW 0x0000000000000020ULL +#define TX_CS_PREF_BUF_PAR_ERR 0x0000000000000010ULL +#define TX_CS_NACK_PREF 0x0000000000000008ULL +#define TX_CS_NACK_PKT_RD 0x0000000000000004ULL +#define TX_CS_CONF_PART_ERR 0x0000000000000002ULL +#define TX_CS_PKT_PRT_ERR 0x0000000000000001ULL + +#define TXDMA_MBH(IDX) (DMC + 0x40030UL + (IDX) * 0x200UL) +#define TXDMA_MBH_MBADDR 0x0000000000000fffULL + +#define TXDMA_MBL(IDX) (DMC + 0x40038UL + (IDX) * 0x200UL) +#define TXDMA_MBL_MBADDR 0x00000000ffffffc0ULL + +#define TX_DMA_PRE_ST(IDX) (DMC + 0x40040UL + (IDX) * 0x200UL) +#define TX_DMA_PRE_ST_SHADOW_HD 0x000000000007ffffULL + +#define TX_RNG_ERR_LOGH(IDX) (DMC + 0x40048UL + (IDX) * 0x200UL) +#define TX_RNG_ERR_LOGH_ERR 0x0000000080000000ULL +#define TX_RNG_ERR_LOGH_MERR 0x0000000040000000ULL +#define TX_RNG_ERR_LOGH_ERRCODE 0x0000000038000000ULL +#define TX_RNG_ERR_LOGH_ERRADDR 0x0000000000000fffULL + +#define TX_RNG_ERR_LOGL(IDX) (DMC + 0x40050UL + (IDX) * 0x200UL) +#define TX_RNG_ERR_LOGL_ERRADDR 0x00000000ffffffffULL + +#define TDMC_INTR_DBG(IDX) (DMC + 0x40060UL + (IDX) * 0x200UL) +#define TDMC_INTR_DBG_MK 0x0000000000008000ULL +#define TDMC_INTR_DBG_MBOX_ERR 0x0000000000000080ULL +#define TDMC_INTR_DBG_PKT_SIZE_ERR 0x0000000000000040ULL +#define TDMC_INTR_DBG_TX_RING_OFLOW 0x0000000000000020ULL +#define TDMC_INTR_DBG_PREF_BUF_PAR_ERR 0x0000000000000010ULL +#define TDMC_INTR_DBG_NACK_PREF 0x0000000000000008ULL +#define TDMC_INTR_DBG_NACK_PKT_RD 0x0000000000000004ULL +#define TDMC_INTR_DBG_CONF_PART_ERR 0x0000000000000002ULL +#define TDMC_INTR_DBG_PKT_PART_ERR 0x0000000000000001ULL + +#define TX_CS_DBG(IDX) (DMC + 0x40068UL + (IDX) * 0x200UL) +#define TX_CS_DBG_PKT_CNT 0x0fff000000000000ULL + +#define TDMC_INJ_PAR_ERR(IDX) (DMC + 0x45040UL + (IDX) * 0x200UL) +#define TDMC_INJ_PAR_ERR_VAL 0x000000000000ffffULL + +#define TDMC_DBG_SEL(IDX) (DMC + 0x45080UL + (IDX) * 0x200UL) +#define TDMC_DBG_SEL_DBG_SEL 0x000000000000003fULL + +#define TDMC_TRAINING_VECTOR(IDX) (DMC + 0x45088UL + (IDX) * 0x200UL) +#define TDMC_TRAINING_VECTOR_VEC 0x00000000ffffffffULL + +#define TXC_DMA_MAX(CHAN) (FZC_TXC + 0x00000UL + (CHAN)*0x1000UL) +#define TXC_DMA_MAX_LEN(CHAN) (FZC_TXC + 0x00008UL + (CHAN)*0x1000UL) + +#define TXC_CONTROL (FZC_TXC + 0x20000UL) +#define TXC_CONTROL_ENABLE 0x0000000000000010ULL +#define TXC_CONTROL_PORT_ENABLE(X) (1 << (X)) + +#define TXC_TRAINING_VEC (FZC_TXC + 0x20008UL) +#define TXC_TRAINING_VEC_MASK 0x00000000ffffffffULL + +#define TXC_DEBUG (FZC_TXC + 0x20010UL) +#define TXC_DEBUG_SELECT 0x000000000000003fULL + +#define TXC_MAX_REORDER (FZC_TXC + 0x20018UL) +#define TXC_MAX_REORDER_PORT3 0x000000000f000000ULL +#define TXC_MAX_REORDER_PORT2 0x00000000000f0000ULL +#define TXC_MAX_REORDER_PORT1 0x0000000000000f00ULL +#define TXC_MAX_REORDER_PORT0 0x000000000000000fULL + +#define TXC_PORT_CTL(PORT) (FZC_TXC + 0x20020UL + (PORT)*0x100UL) +#define TXC_PORT_CTL_CLR_ALL_STAT 0x0000000000000001ULL + +#define TXC_PKT_STUFFED(PORT) (FZC_TXC + 0x20030UL + (PORT)*0x100UL) +#define TXC_PKT_STUFFED_PP_REORDER 0x00000000ffff0000ULL +#define TXC_PKT_STUFFED_PP_PACKETASSY 0x000000000000ffffULL + +#define TXC_PKT_XMIT(PORT) (FZC_TXC + 0x20038UL + (PORT)*0x100UL) +#define TXC_PKT_XMIT_BYTES 0x00000000ffff0000ULL +#define TXC_PKT_XMIT_PKTS 0x000000000000ffffULL + +#define TXC_ROECC_CTL(PORT) (FZC_TXC + 0x20040UL + (PORT)*0x100UL) +#define TXC_ROECC_CTL_DISABLE_UE 0x0000000080000000ULL +#define TXC_ROECC_CTL_DBL_BIT_ERR 0x0000000000020000ULL +#define TXC_ROECC_CTL_SNGL_BIT_ERR 0x0000000000010000ULL +#define TXC_ROECC_CTL_ALL_PKTS 0x0000000000000400ULL +#define TXC_ROECC_CTL_ALT_PKTS 0x0000000000000200ULL +#define TXC_ROECC_CTL_ONE_PKT_ONLY 0x0000000000000100ULL +#define TXC_ROECC_CTL_LST_PKT_LINE 0x0000000000000004ULL +#define TXC_ROECC_CTL_2ND_PKT_LINE 0x0000000000000002ULL +#define TXC_ROECC_CTL_1ST_PKT_LINE 0x0000000000000001ULL + +#define TXC_ROECC_ST(PORT) (FZC_TXC + 0x20048UL + (PORT)*0x100UL) +#define TXC_ROECC_CLR_ST 0x0000000080000000ULL +#define TXC_ROECC_CE 0x0000000000020000ULL +#define TXC_ROECC_UE 0x0000000000010000ULL +#define TXC_ROECC_ST_ECC_ADDR 0x00000000000003ffULL + +#define TXC_RO_DATA0(PORT) (FZC_TXC + 0x20050UL + (PORT)*0x100UL) +#define TXC_RO_DATA0_DATA0 0x00000000ffffffffULL /* bits 31:0 */ + +#define TXC_RO_DATA1(PORT) (FZC_TXC + 0x20058UL + (PORT)*0x100UL) +#define TXC_RO_DATA1_DATA1 0x00000000ffffffffULL /* bits 63:32 */ + +#define TXC_RO_DATA2(PORT) (FZC_TXC + 0x20060UL + (PORT)*0x100UL) +#define TXC_RO_DATA2_DATA2 0x00000000ffffffffULL /* bits 95:64 */ + +#define TXC_RO_DATA3(PORT) (FZC_TXC + 0x20068UL + (PORT)*0x100UL) +#define TXC_RO_DATA3_DATA3 0x00000000ffffffffULL /* bits 127:96 */ + +#define TXC_RO_DATA4(PORT) (FZC_TXC + 0x20070UL + (PORT)*0x100UL) +#define TXC_RO_DATA4_DATA4 0x0000000000ffffffULL /* bits 151:128 */ + +#define TXC_SFECC_CTL(PORT) (FZC_TXC + 0x20078UL + (PORT)*0x100UL) +#define TXC_SFECC_CTL_DISABLE_UE 0x0000000080000000ULL +#define TXC_SFECC_CTL_DBL_BIT_ERR 0x0000000000020000ULL +#define TXC_SFECC_CTL_SNGL_BIT_ERR 0x0000000000010000ULL +#define TXC_SFECC_CTL_ALL_PKTS 0x0000000000000400ULL +#define TXC_SFECC_CTL_ALT_PKTS 0x0000000000000200ULL +#define TXC_SFECC_CTL_ONE_PKT_ONLY 0x0000000000000100ULL +#define TXC_SFECC_CTL_LST_PKT_LINE 0x0000000000000004ULL +#define TXC_SFECC_CTL_2ND_PKT_LINE 0x0000000000000002ULL +#define TXC_SFECC_CTL_1ST_PKT_LINE 0x0000000000000001ULL + +#define TXC_SFECC_ST(PORT) (FZC_TXC + 0x20080UL + (PORT)*0x100UL) +#define TXC_SFECC_ST_CLR_ST 0x0000000080000000ULL +#define TXC_SFECC_ST_CE 0x0000000000020000ULL +#define TXC_SFECC_ST_UE 0x0000000000010000ULL +#define TXC_SFECC_ST_ECC_ADDR 0x00000000000003ffULL + +#define TXC_SF_DATA0(PORT) (FZC_TXC + 0x20088UL + (PORT)*0x100UL) +#define TXC_SF_DATA0_DATA0 0x00000000ffffffffULL /* bits 31:0 */ + +#define TXC_SF_DATA1(PORT) (FZC_TXC + 0x20090UL + (PORT)*0x100UL) +#define TXC_SF_DATA1_DATA1 0x00000000ffffffffULL /* bits 63:32 */ + +#define TXC_SF_DATA2(PORT) (FZC_TXC + 0x20098UL + (PORT)*0x100UL) +#define TXC_SF_DATA2_DATA2 0x00000000ffffffffULL /* bits 95:64 */ + +#define TXC_SF_DATA3(PORT) (FZC_TXC + 0x200a0UL + (PORT)*0x100UL) +#define TXC_SF_DATA3_DATA3 0x00000000ffffffffULL /* bits 127:96 */ + +#define TXC_SF_DATA4(PORT) (FZC_TXC + 0x200a8UL + (PORT)*0x100UL) +#define TXC_SF_DATA4_DATA4 0x0000000000ffffffULL /* bits 151:128 */ + +#define TXC_RO_TIDS(PORT) (FZC_TXC + 0x200b0UL + (PORT)*0x100UL) +#define TXC_RO_TIDS_IN_USE 0x00000000ffffffffULL + +#define TXC_RO_STATE0(PORT) (FZC_TXC + 0x200b8UL + (PORT)*0x100UL) +#define TXC_RO_STATE0_DUPLICATE_TID 0x00000000ffffffffULL + +#define TXC_RO_STATE1(PORT) (FZC_TXC + 0x200c0UL + (PORT)*0x100UL) +#define TXC_RO_STATE1_UNUSED_TID 0x00000000ffffffffULL + +#define TXC_RO_STATE2(PORT) (FZC_TXC + 0x200c8UL + (PORT)*0x100UL) +#define TXC_RO_STATE2_TRANS_TIMEOUT 0x00000000ffffffffULL + +#define TXC_RO_STATE3(PORT) (FZC_TXC + 0x200d0UL + (PORT)*0x100UL) +#define TXC_RO_STATE3_ENAB_SPC_WMARK 0x0000000080000000ULL +#define TXC_RO_STATE3_RO_SPC_WMARK 0x000000007fe00000ULL +#define TXC_RO_STATE3_ROFIFO_SPC_AVAIL 0x00000000001ff800ULL +#define TXC_RO_STATE3_ENAB_RO_WMARK 0x0000000000000100ULL +#define TXC_RO_STATE3_HIGH_RO_USED 0x00000000000000f0ULL +#define TXC_RO_STATE3_NUM_RO_USED 0x000000000000000fULL + +#define TXC_RO_CTL(PORT) (FZC_TXC + 0x200d8UL + (PORT)*0x100UL) +#define TXC_RO_CTL_CLR_FAIL_STATE 0x0000000080000000ULL +#define TXC_RO_CTL_RO_ADDR 0x000000000f000000ULL +#define TXC_RO_CTL_ADDR_FAILED 0x0000000000400000ULL +#define TXC_RO_CTL_DMA_FAILED 0x0000000000200000ULL +#define TXC_RO_CTL_LEN_FAILED 0x0000000000100000ULL +#define TXC_RO_CTL_CAPT_ADDR_FAILED 0x0000000000040000ULL +#define TXC_RO_CTL_CAPT_DMA_FAILED 0x0000000000020000ULL +#define TXC_RO_CTL_CAPT_LEN_FAILED 0x0000000000010000ULL +#define TXC_RO_CTL_RO_STATE_RD_DONE 0x0000000000000080ULL +#define TXC_RO_CTL_RO_STATE_WR_DONE 0x0000000000000040ULL +#define TXC_RO_CTL_RO_STATE_RD 0x0000000000000020ULL +#define TXC_RO_CTL_RO_STATE_WR 0x0000000000000010ULL +#define TXC_RO_CTL_RO_STATE_ADDR 0x000000000000000fULL + +#define TXC_RO_ST_DATA0(PORT) (FZC_TXC + 0x200e0UL + (PORT)*0x100UL) +#define TXC_RO_ST_DATA0_DATA0 0x00000000ffffffffULL + +#define TXC_RO_ST_DATA1(PORT) (FZC_TXC + 0x200e8UL + (PORT)*0x100UL) +#define TXC_RO_ST_DATA1_DATA1 0x00000000ffffffffULL + +#define TXC_RO_ST_DATA2(PORT) (FZC_TXC + 0x200f0UL + (PORT)*0x100UL) +#define TXC_RO_ST_DATA2_DATA2 0x00000000ffffffffULL + +#define TXC_RO_ST_DATA3(PORT) (FZC_TXC + 0x200f8UL + (PORT)*0x100UL) +#define TXC_RO_ST_DATA3_DATA3 0x00000000ffffffffULL + +#define TXC_PORT_PACKET_REQ(PORT) (FZC_TXC + 0x20100UL + (PORT)*0x100UL) +#define TXC_PORT_PACKET_REQ_GATHER_REQ 0x00000000f0000000ULL +#define TXC_PORT_PACKET_REQ_PKT_REQ 0x000000000fff0000ULL +#define TXC_PORT_PACKET_REQ_PERR_ABRT 0x000000000000ffffULL + + /* bits are same as TXC_INT_STAT */ +#define TXC_INT_STAT_DBG (FZC_TXC + 0x20420UL) + +#define TXC_INT_STAT (FZC_TXC + 0x20428UL) +#define TXC_INT_STAT_VAL_SHIFT(PORT) ((PORT) * 8) +#define TXC_INT_STAT_VAL(PORT) (0x3f << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_SF_CE(PORT) (0x01 << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_SF_UE(PORT) (0x02 << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_RO_CE(PORT) (0x04 << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_RO_UE(PORT) (0x08 << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_REORDER_ERR(PORT) (0x10 << TXC_INT_STAT_VAL_SHIFT(PORT)) +#define TXC_INT_STAT_PKTASM_DEAD(PORT) (0x20 << TXC_INT_STAT_VAL_SHIFT(PORT)) + +#define TXC_INT_MASK (FZC_TXC + 0x20430UL) +#define TXC_INT_MASK_VAL_SHIFT(PORT) ((PORT) * 8) +#define TXC_INT_MASK_VAL(PORT) (0x3f << TXC_INT_STAT_VAL_SHIFT(PORT)) + +#define TXC_INT_MASK_SF_CE 0x01 +#define TXC_INT_MASK_SF_UE 0x02 +#define TXC_INT_MASK_RO_CE 0x04 +#define TXC_INT_MASK_RO_UE 0x08 +#define TXC_INT_MASK_REORDER_ERR 0x10 +#define TXC_INT_MASK_PKTASM_DEAD 0x20 +#define TXC_INT_MASK_ALL 0x3f + +#define TXC_PORT_DMA(IDX) (FZC_TXC + 0x20028UL + (IDX)*0x100UL) + +#define ESPC_PIO_EN (FZC_PROM + 0x40000UL) +#define ESPC_PIO_EN_ENABLE 0x0000000000000001ULL + +#define ESPC_PIO_STAT (FZC_PROM + 0x40008UL) +#define ESPC_PIO_STAT_READ_START 0x0000000080000000ULL +#define ESPC_PIO_STAT_READ_END 0x0000000040000000ULL +#define ESPC_PIO_STAT_WRITE_INIT 0x0000000020000000ULL +#define ESPC_PIO_STAT_WRITE_END 0x0000000010000000ULL +#define ESPC_PIO_STAT_ADDR 0x0000000003ffff00ULL +#define ESPC_PIO_STAT_ADDR_SHIFT 8 +#define ESPC_PIO_STAT_DATA 0x00000000000000ffULL +#define ESPC_PIO_STAT_DATA_SHIFT 0 + +#define ESPC_NCR(IDX) (FZC_PROM + 0x40020UL + (IDX)*0x8UL) +#define ESPC_NCR_VAL 0x00000000ffffffffULL + +#define ESPC_MAC_ADDR0 ESPC_NCR(0) +#define ESPC_MAC_ADDR1 ESPC_NCR(1) +#define ESPC_NUM_PORTS_MACS ESPC_NCR(2) +#define ESPC_NUM_PORTS_MACS_VAL 0x00000000000000ffULL +#define ESPC_MOD_STR_LEN ESPC_NCR(4) +#define ESPC_MOD_STR_1 ESPC_NCR(5) +#define ESPC_MOD_STR_2 ESPC_NCR(6) +#define ESPC_MOD_STR_3 ESPC_NCR(7) +#define ESPC_MOD_STR_4 ESPC_NCR(8) +#define ESPC_MOD_STR_5 ESPC_NCR(9) +#define ESPC_MOD_STR_6 ESPC_NCR(10) +#define ESPC_MOD_STR_7 ESPC_NCR(11) +#define ESPC_MOD_STR_8 ESPC_NCR(12) +#define ESPC_BD_MOD_STR_LEN ESPC_NCR(13) +#define ESPC_BD_MOD_STR_1 ESPC_NCR(14) +#define ESPC_BD_MOD_STR_2 ESPC_NCR(15) +#define ESPC_BD_MOD_STR_3 ESPC_NCR(16) +#define ESPC_BD_MOD_STR_4 ESPC_NCR(17) + +#define ESPC_PHY_TYPE ESPC_NCR(18) +#define ESPC_PHY_TYPE_PORT0 0x00000000ff000000ULL +#define ESPC_PHY_TYPE_PORT0_SHIFT 24 +#define ESPC_PHY_TYPE_PORT1 0x0000000000ff0000ULL +#define ESPC_PHY_TYPE_PORT1_SHIFT 16 +#define ESPC_PHY_TYPE_PORT2 0x000000000000ff00ULL +#define ESPC_PHY_TYPE_PORT2_SHIFT 8 +#define ESPC_PHY_TYPE_PORT3 0x00000000000000ffULL +#define ESPC_PHY_TYPE_PORT3_SHIFT 0 + +#define ESPC_PHY_TYPE_1G_COPPER 3 +#define ESPC_PHY_TYPE_1G_FIBER 2 +#define ESPC_PHY_TYPE_10G_COPPER 1 +#define ESPC_PHY_TYPE_10G_FIBER 0 + +#define ESPC_MAX_FM_SZ ESPC_NCR(19) + +#define ESPC_INTR_NUM ESPC_NCR(20) +#define ESPC_INTR_NUM_PORT0 0x00000000ff000000ULL +#define ESPC_INTR_NUM_PORT1 0x0000000000ff0000ULL +#define ESPC_INTR_NUM_PORT2 0x000000000000ff00ULL +#define ESPC_INTR_NUM_PORT3 0x00000000000000ffULL + +#define ESPC_VER_IMGSZ ESPC_NCR(21) +#define ESPC_VER_IMGSZ_IMGSZ 0x00000000ffff0000ULL +#define ESPC_VER_IMGSZ_IMGSZ_SHIFT 16 +#define ESPC_VER_IMGSZ_VER 0x000000000000ffffULL +#define ESPC_VER_IMGSZ_VER_SHIFT 0 + +#define ESPC_CHKSUM ESPC_NCR(22) +#define ESPC_CHKSUM_SUM 0x00000000000000ffULL + +#define ESPC_EEPROM_SIZE 0x100000 + +#define CLASS_CODE_UNRECOG 0x00 +#define CLASS_CODE_DUMMY1 0x01 +#define CLASS_CODE_ETHERTYPE1 0x02 +#define CLASS_CODE_ETHERTYPE2 0x03 +#define CLASS_CODE_USER_PROG1 0x04 +#define CLASS_CODE_USER_PROG2 0x05 +#define CLASS_CODE_USER_PROG3 0x06 +#define CLASS_CODE_USER_PROG4 0x07 +#define CLASS_CODE_TCP_IPV4 0x08 +#define CLASS_CODE_UDP_IPV4 0x09 +#define CLASS_CODE_AH_ESP_IPV4 0x0a +#define CLASS_CODE_SCTP_IPV4 0x0b +#define CLASS_CODE_TCP_IPV6 0x0c +#define CLASS_CODE_UDP_IPV6 0x0d +#define CLASS_CODE_AH_ESP_IPV6 0x0e +#define CLASS_CODE_SCTP_IPV6 0x0f +#define CLASS_CODE_ARP 0x10 +#define CLASS_CODE_RARP 0x11 +#define CLASS_CODE_DUMMY2 0x12 +#define CLASS_CODE_DUMMY3 0x13 +#define CLASS_CODE_DUMMY4 0x14 +#define CLASS_CODE_DUMMY5 0x15 +#define CLASS_CODE_DUMMY6 0x16 +#define CLASS_CODE_DUMMY7 0x17 +#define CLASS_CODE_DUMMY8 0x18 +#define CLASS_CODE_DUMMY9 0x19 +#define CLASS_CODE_DUMMY10 0x1a +#define CLASS_CODE_DUMMY11 0x1b +#define CLASS_CODE_DUMMY12 0x1c +#define CLASS_CODE_DUMMY13 0x1d +#define CLASS_CODE_DUMMY14 0x1e +#define CLASS_CODE_DUMMY15 0x1f + +/* Logical devices and device groups */ +#define LDN_RXDMA(CHAN) (0 + (CHAN)) +#define LDN_RESV1(OFF) (16 + (OFF)) +#define LDN_TXDMA(CHAN) (32 + (CHAN)) +#define LDN_RESV2(OFF) (56 + (OFF)) +#define LDN_MIF 63 +#define LDN_MAC(PORT) (64 + (PORT)) +#define LDN_DEVICE_ERROR 68 +#define LDN_MAX LDN_DEVICE_ERROR + +#define NIU_LDG_MIN 0 +#define NIU_LDG_MAX 63 +#define NIU_NUM_LDG 64 +#define LDG_INVALID 0xff + +/* PHY stuff */ +#define NIU_PMA_PMD_DEV_ADDR 1 +#define NIU_PCS_DEV_ADDR 3 + +#define NIU_PHY_ID_MASK 0xfffff0f0 +#define NIU_PHY_ID_BCM8704 0x00206030 +#define NIU_PHY_ID_BCM5464R 0x002060b0 + +#define BCM8704_PMA_PMD_DEV_ADDR 1 +#define BCM8704_PCS_DEV_ADDR 2 +#define BCM8704_USER_DEV3_ADDR 3 +#define BCM8704_PHYXS_DEV_ADDR 4 +#define BCM8704_USER_DEV4_ADDR 4 + +#define BCM8704_PMD_RCV_SIGDET 0x000a +#define PMD_RCV_SIGDET_LANE3 0x0010 +#define PMD_RCV_SIGDET_LANE2 0x0008 +#define PMD_RCV_SIGDET_LANE1 0x0004 +#define PMD_RCV_SIGDET_LANE0 0x0002 +#define PMD_RCV_SIGDET_GLOBAL 0x0001 + +#define BCM8704_PCS_10G_R_STATUS 0x0020 +#define PCS_10G_R_STATUS_LINKSTAT 0x1000 +#define PCS_10G_R_STATUS_PRBS31_ABLE 0x0004 +#define PCS_10G_R_STATUS_HI_BER 0x0002 +#define PCS_10G_R_STATUS_BLK_LOCK 0x0001 + +#define BCM8704_USER_CONTROL 0xc800 +#define USER_CONTROL_OPTXENB_LVL 0x8000 +#define USER_CONTROL_OPTXRST_LVL 0x4000 +#define USER_CONTROL_OPBIASFLT_LVL 0x2000 +#define USER_CONTROL_OBTMPFLT_LVL 0x1000 +#define USER_CONTROL_OPPRFLT_LVL 0x0800 +#define USER_CONTROL_OPTXFLT_LVL 0x0400 +#define USER_CONTROL_OPRXLOS_LVL 0x0200 +#define USER_CONTROL_OPRXFLT_LVL 0x0100 +#define USER_CONTROL_OPTXON_LVL 0x0080 +#define USER_CONTROL_RES1 0x007f +#define USER_CONTROL_RES1_SHIFT 0 + +#define BCM8704_USER_ANALOG_CLK 0xc801 +#define BCM8704_USER_PMD_RX_CONTROL 0xc802 + +#define BCM8704_USER_PMD_TX_CONTROL 0xc803 +#define USER_PMD_TX_CTL_RES1 0xfe00 +#define USER_PMD_TX_CTL_XFP_CLKEN 0x0100 +#define USER_PMD_TX_CTL_TX_DAC_TXD 0x00c0 +#define USER_PMD_TX_CTL_TX_DAC_TXD_SH 6 +#define USER_PMD_TX_CTL_TX_DAC_TXCK 0x0030 +#define USER_PMD_TX_CTL_TX_DAC_TXCK_SH 4 +#define USER_PMD_TX_CTL_TSD_LPWREN 0x0008 +#define USER_PMD_TX_CTL_TSCK_LPWREN 0x0004 +#define USER_PMD_TX_CTL_CMU_LPWREN 0x0002 +#define USER_PMD_TX_CTL_SFIFORST 0x0001 + +#define BCM8704_USER_ANALOG_STATUS0 0xc804 +#define BCM8704_USER_OPT_DIGITAL_CTRL 0xc808 +#define BCM8704_USER_TX_ALARM_STATUS 0x9004 + +#define USER_ODIG_CTRL_FMODE 0x8000 +#define USER_ODIG_CTRL_TX_PDOWN 0x4000 +#define USER_ODIG_CTRL_RX_PDOWN 0x2000 +#define USER_ODIG_CTRL_EFILT_EN 0x1000 +#define USER_ODIG_CTRL_OPT_RST 0x0800 +#define USER_ODIG_CTRL_PCS_TIB 0x0400 +#define USER_ODIG_CTRL_PCS_RI 0x0200 +#define USER_ODIG_CTRL_RESV1 0x0180 +#define USER_ODIG_CTRL_GPIOS 0x0060 +#define USER_ODIG_CTRL_GPIOS_SHIFT 5 +#define USER_ODIG_CTRL_RESV2 0x0010 +#define USER_ODIG_CTRL_LB_ERR_DIS 0x0008 +#define USER_ODIG_CTRL_RESV3 0x0006 +#define USER_ODIG_CTRL_TXONOFF_PD_DIS 0x0001 + +#define BCM8704_PHYXS_XGXS_LANE_STAT 0x0018 +#define PHYXS_XGXS_LANE_STAT_ALINGED 0x1000 +#define PHYXS_XGXS_LANE_STAT_PATTEST 0x0800 +#define PHYXS_XGXS_LANE_STAT_MAGIC 0x0400 +#define PHYXS_XGXS_LANE_STAT_LANE3 0x0008 +#define PHYXS_XGXS_LANE_STAT_LANE2 0x0004 +#define PHYXS_XGXS_LANE_STAT_LANE1 0x0002 +#define PHYXS_XGXS_LANE_STAT_LANE0 0x0001 + +#define BCM5464R_AUX_CTL 24 +#define BCM5464R_AUX_CTL_EXT_LB 0x8000 +#define BCM5464R_AUX_CTL_EXT_PLEN 0x4000 +#define BCM5464R_AUX_CTL_ER1000 0x3000 +#define BCM5464R_AUX_CTL_ER1000_SHIFT 12 +#define BCM5464R_AUX_CTL_RESV1 0x0800 +#define BCM5464R_AUX_CTL_WRITE_1 0x0400 +#define BCM5464R_AUX_CTL_RESV2 0x0300 +#define BCM5464R_AUX_CTL_PRESP_DIS 0x0080 +#define BCM5464R_AUX_CTL_RESV3 0x0040 +#define BCM5464R_AUX_CTL_ER100 0x0030 +#define BCM5464R_AUX_CTL_ER100_SHIFT 4 +#define BCM5464R_AUX_CTL_DIAG_MODE 0x0008 +#define BCM5464R_AUX_CTL_SR_SEL 0x0007 +#define BCM5464R_AUX_CTL_SR_SEL_SHIFT 0 + +#define BCM5464R_CTRL1000_AS_MASTER 0x0800 +#define BCM5464R_CTRL1000_ENABLE_AS_MASTER 0x1000 + +#define RCR_ENTRY_MULTI 0x8000000000000000ULL +#define RCR_ENTRY_PKT_TYPE 0x6000000000000000ULL +#define RCR_ENTRY_PKT_TYPE_SHIFT 61 +#define RCR_ENTRY_ZERO_COPY 0x1000000000000000ULL +#define RCR_ENTRY_NOPORT 0x0800000000000000ULL +#define RCR_ENTRY_PROMISC 0x0400000000000000ULL +#define RCR_ENTRY_ERROR 0x0380000000000000ULL +#define RCR_ENTRY_DCF_ERR 0x0040000000000000ULL +#define RCR_ENTRY_L2_LEN 0x003fff0000000000ULL +#define RCR_ENTRY_L2_LEN_SHIFT 40 +#define RCR_ENTRY_PKTBUFSZ 0x000000c000000000ULL +#define RCR_ENTRY_PKTBUFSZ_SHIFT 38 +#define RCR_ENTRY_PKT_BUF_ADDR 0x0000003fffffffffULL /* bits 43:6 */ +#define RCR_ENTRY_PKT_BUF_ADDR_SHIFT 6 + +#define RCR_PKT_TYPE_OTHER 0x0 +#define RCR_PKT_TYPE_TCP 0x1 +#define RCR_PKT_TYPE_UDP 0x2 +#define RCR_PKT_TYPE_SCTP 0x3 + +#define NIU_RXPULL_MAX ETH_HLEN + +struct rx_pkt_hdr0 { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 inputport:2, + maccheck:1, + class:4; + u8 vlan:1, + llcsnap:1, + noport:1, + badip:1, + tcamhit:1, + tres:2, + tzfvld:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 class:4, + maccheck:1, + inputport:2; + u8 tzfvld:1, + tres:2, + tcamhit:1, + badip:1, + noport:1, + llcsnap:1, + vlan:1; +#endif +}; + +struct rx_pkt_hdr1 { + u8 hwrsvd1; + u8 tcammatch; +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 hwrsvd2:2, + hashit:1, + exact:1, + hzfvld:1, + hashsidx:3; +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 hashsidx:3, + hzfvld:1, + exact:1, + hashit:1, + hwrsvd2:2; +#endif + u8 zcrsvd; + + /* Bits 11:8 of zero copy flow ID. */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 hwrsvd3:4, zflowid0:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 zflowid0:4, hwrsvd3:4; +#endif + + /* Bits 7:0 of zero copy flow ID. */ + u8 zflowid1; + + /* Bits 15:8 of hash value, H2. */ + u8 hashval2_0; + + /* Bits 7:0 of hash value, H2. */ + u8 hashval2_1; + + /* Bits 19:16 of hash value, H1. */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 hwrsvd4:4, hashval1_0:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 hashval1_0:4, hwrsvd4:4; +#endif + + /* Bits 15:8 of hash value, H1. */ + u8 hashval1_1; + + /* Bits 7:0 of hash value, H1. */ + u8 hashval1_2; + + u8 usrdata_0; /* Bits 39:32 of user data. */ + u8 usrdata_1; /* Bits 31:24 of user data. */ + u8 usrdata_2; /* Bits 23:16 of user data. */ + u8 usrdata_3; /* Bits 15:8 of user data. */ + u8 usrdata_4; /* Bits 7:0 of user data. */ +}; + +struct tx_dma_mbox { + u64 tx_dma_pre_st; + u64 tx_cs; + u64 tx_ring_kick; + u64 tx_ring_hdl; + u64 resv1; + u32 tx_rng_err_logl; + u32 tx_rng_err_logh; + u64 resv2; + u64 resv3; +}; + +struct tx_pkt_hdr { + __le64 flags; +#define TXHDR_PAD 0x0000000000000007ULL +#define TXHDR_PAD_SHIFT 0 +#define TXHDR_LEN 0x000000003fff0000ULL +#define TXHDR_LEN_SHIFT 16 +#define TXHDR_L4STUFF 0x0000003f00000000ULL +#define TXHDR_L4STUFF_SHIFT 32 +#define TXHDR_L4START 0x00003f0000000000ULL +#define TXHDR_L4START_SHIFT 40 +#define TXHDR_L3START 0x000f000000000000ULL +#define TXHDR_L3START_SHIFT 48 +#define TXHDR_IHL 0x00f0000000000000ULL +#define TXHDR_IHL_SHIFT 52 +#define TXHDR_VLAN 0x0100000000000000ULL +#define TXHDR_LLC 0x0200000000000000ULL +#define TXHDR_IP_VER 0x2000000000000000ULL +#define TXHDR_CSUM_NONE 0x0000000000000000ULL +#define TXHDR_CSUM_TCP 0x4000000000000000ULL +#define TXHDR_CSUM_UDP 0x8000000000000000ULL +#define TXHDR_CSUM_SCTP 0xc000000000000000ULL + __le64 resv; +}; + +#define TX_DESC_SOP 0x8000000000000000ULL +#define TX_DESC_MARK 0x4000000000000000ULL +#define TX_DESC_NUM_PTR 0x3c00000000000000ULL +#define TX_DESC_NUM_PTR_SHIFT 58 +#define TX_DESC_TR_LEN 0x01fff00000000000ULL +#define TX_DESC_TR_LEN_SHIFT 44 +#define TX_DESC_SAD 0x00000fffffffffffULL +#define TX_DESC_SAD_SHIFT 0 + +struct tx_buff_info { + struct sk_buff *skb; + u64 mapping; +}; + +struct txdma_mailbox { + __le64 tx_dma_pre_st; + __le64 tx_cs; + __le64 tx_ring_kick; + __le64 tx_ring_hdl; + __le64 resv1; + __le32 tx_rng_err_logl; + __le32 tx_rng_err_logh; + __le64 resv2[2]; +} __attribute__((aligned(64))); + +#define MAX_TX_RING_SIZE 256 +#define MAX_TX_DESC_LEN 4076 + +struct tx_ring_info { + struct tx_buff_info tx_buffs[MAX_TX_RING_SIZE]; + struct niu *np; + u64 tx_cs; + int pending; + int prod; + int cons; + int wrap_bit; + u16 last_pkt_cnt; + u16 tx_channel; + u16 mark_counter; + u16 mark_freq; + u16 mark_pending; + u16 __pad; + struct txdma_mailbox *mbox; + __le64 *descr; + + u64 tx_packets; + u64 tx_bytes; + u64 tx_errors; + + u64 mbox_dma; + u64 descr_dma; + int max_burst; +}; + +#define NEXT_TX(tp, index) \ + (((index) + 1) < (tp)->pending ? ((index) + 1) : 0) + +static inline u32 niu_tx_avail(struct tx_ring_info *tp) +{ + return (tp->pending - + ((tp->prod - tp->cons) & (MAX_TX_RING_SIZE - 1))); +} + +struct rxdma_mailbox { + __le64 rx_dma_ctl_stat; + __le64 rbr_stat; + __le32 rbr_hdl; + __le32 rbr_hdh; + __le64 resv1; + __le32 rcrstat_c; + __le32 rcrstat_b; + __le64 rcrstat_a; + __le64 resv2[2]; +} __attribute__((aligned(64))); + +#define MAX_RBR_RING_SIZE 128 +#define MAX_RCR_RING_SIZE (MAX_RBR_RING_SIZE * 2) + +#define RBR_REFILL_MIN 16 + +#define RX_SKB_ALLOC_SIZE 128 + NET_IP_ALIGN + +#undef NIU_NAPI_STRUCT + +struct rx_ring_info { + struct niu *np; + int rx_channel; + u16 rbr_block_size; + u16 rbr_blocks_per_page; + u16 rbr_sizes[4]; + unsigned int rcr_index; + unsigned int rcr_table_size; + unsigned int rbr_index; + unsigned int rbr_pending; + unsigned int rbr_refill_pending; + unsigned int rbr_kick_thresh; + unsigned int rbr_table_size; + struct page **rxhash; + struct rxdma_mailbox *mbox; + __le64 *rcr; + __le32 *rbr; +#define RBR_DESCR_ADDR_SHIFT 12 + + u64 rx_packets; + u64 rx_bytes; + u64 rx_dropped; + u64 rx_errors; + + u64 mbox_dma; + u64 rcr_dma; + u64 rbr_dma; + + /* WRED */ + int nonsyn_window; + int nonsyn_threshold; + int syn_window; + int syn_threshold; + + /* interrupt mitigation */ + int rcr_pkt_threshold; + int rcr_timeout; +}; + +#define NEXT_RCR(rp, index) \ + (((index) + 1) < (rp)->rcr_table_size ? ((index) + 1) : 0) +#define NEXT_RBR(rp, index) \ + (((index) + 1) < (rp)->rbr_table_size ? ((index) + 1) : 0) + +#define NIU_MAX_PORTS 4 +#define NIU_NUM_RXCHAN 16 +#define NIU_NUM_TXCHAN 24 +#define MAC_NUM_HASH 16 + +#define NIU_MAX_MTU 9216 + +#define NIU_VPD_MIN_MAJOR 3 +#define NIU_VPD_MIN_MINOR 4 + +#define NIU_VPD_MODEL_MAX 32 +#define NIU_VPD_BD_MODEL_MAX 16 +#define NIU_VPD_VERSION_MAX 64 +#define NIU_VPD_PHY_TYPE_MAX 8 + +struct niu_vpd { + char model[NIU_VPD_MODEL_MAX]; + char board_model[NIU_VPD_BD_MODEL_MAX]; + char version[NIU_VPD_VERSION_MAX]; + char phy_type[NIU_VPD_PHY_TYPE_MAX]; + u8 mac_num; + u8 __pad; + u8 local_mac[6]; + int fcode_major; + int fcode_minor; +}; + +struct niu_altmac_rdc { + u8 alt_mac_num; + u8 rdc_num; + u8 mac_pref; +}; + +struct niu_vlan_rdc { + u8 rdc_num; + u8 vlan_pref; +}; + +struct niu_classifier { + struct niu_altmac_rdc alt_mac_mappings[16]; + struct niu_vlan_rdc vlan_mappings[ENET_VLAN_TBL_NUM_ENTRIES]; + + u16 tcam_index; + u16 num_alt_mac_mappings; + + u32 h1_init; + u16 h2_init; +}; + +#define NIU_NUM_RDC_TABLES 8 +#define NIU_RDC_TABLE_SLOTS 16 + +struct rdc_table { + u8 rxdma_channel[NIU_RDC_TABLE_SLOTS]; +}; + +struct niu_rdc_tables { + struct rdc_table tables[NIU_NUM_RDC_TABLES]; + int first_table_num; + int num_tables; +}; + +#define PHY_TYPE_PMA_PMD 0 +#define PHY_TYPE_PCS 1 +#define PHY_TYPE_MII 2 +#define PHY_TYPE_MAX 3 + +struct phy_probe_info { + u32 phy_id[PHY_TYPE_MAX][NIU_MAX_PORTS]; + u8 phy_port[PHY_TYPE_MAX][NIU_MAX_PORTS]; + u8 cur[PHY_TYPE_MAX]; + + struct device_attribute phy_port_attrs[PHY_TYPE_MAX * NIU_MAX_PORTS]; + struct device_attribute phy_type_attrs[PHY_TYPE_MAX * NIU_MAX_PORTS]; + struct device_attribute phy_id_attrs[PHY_TYPE_MAX * NIU_MAX_PORTS]; +}; + +struct niu_tcam_entry { + u64 key[4]; + u64 key_mask[4]; + u64 assoc_data; +}; + +struct device_node; +union niu_parent_id { + struct { + int domain; + int bus; + int device; + } pci; + struct device_node *of; +}; + +struct niu; +struct niu_parent { + struct platform_device *plat_dev; + int index; + + union niu_parent_id id; + + struct niu *ports[NIU_MAX_PORTS]; + + atomic_t refcnt; + struct list_head list; + + spinlock_t lock; + + u32 flags; +#define PARENT_FLGS_CLS_HWINIT 0x00000001 + + u32 port_phy; +#define PORT_PHY_UNKNOWN 0x00000000 +#define PORT_PHY_INVALID 0xffffffff +#define PORT_TYPE_10G 0x01 +#define PORT_TYPE_1G 0x02 +#define PORT_TYPE_MASK 0x03 + + u8 rxchan_per_port[NIU_MAX_PORTS]; + u8 txchan_per_port[NIU_MAX_PORTS]; + + struct niu_rdc_tables rdc_group_cfg[NIU_MAX_PORTS]; + u8 rdc_default[NIU_MAX_PORTS]; + + u8 ldg_map[LDN_MAX + 1]; + + u8 plat_type; +#define PLAT_TYPE_INVALID 0x00 +#define PLAT_TYPE_ATLAS 0x01 +#define PLAT_TYPE_NIU 0x02 +#define PLAT_TYPE_VF_P0 0x03 +#define PLAT_TYPE_VF_P1 0x04 + + u8 num_ports; + + u16 tcam_num_entries; +#define NIU_PCI_TCAM_ENTRIES 256 +#define NIU_NONPCI_TCAM_ENTRIES 128 +#define NIU_TCAM_ENTRIES_MAX 256 + + int rxdma_clock_divider; + + struct phy_probe_info phy_probe_info; + + struct niu_tcam_entry tcam[NIU_TCAM_ENTRIES_MAX]; + u64 l2_cls[2]; + u64 l3_cls[4]; + u64 tcam_key[12]; + u64 flow_key[12]; +}; + +struct niu_ops { + void *(*alloc_coherent)(struct device *dev, size_t size, + u64 *handle, gfp_t flag); + void (*free_coherent)(struct device *dev, size_t size, + void *cpu_addr, u64 handle); + u64 (*map_page)(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction); + void (*unmap_page)(struct device *dev, u64 dma_address, + size_t size, enum dma_data_direction direction); + u64 (*map_single)(struct device *dev, void *cpu_addr, + size_t size, + enum dma_data_direction direction); + void (*unmap_single)(struct device *dev, u64 dma_address, + size_t size, enum dma_data_direction direction); +}; + +struct niu_link_config { + /* Describes what we're trying to get. */ + u32 advertising; + u32 supported; + u16 speed; + u8 duplex; + u8 autoneg; + + /* Describes what we actually have. */ + u16 active_speed; + u8 active_duplex; +#define SPEED_INVALID 0xffff +#define DUPLEX_INVALID 0xff +#define AUTONEG_INVALID 0xff + + u8 loopback_mode; +#define LOOPBACK_DISABLED 0x00 +#define LOOPBACK_PHY 0x01 +#define LOOPBACK_MAC 0x02 +}; + +struct niu_ldg { +#ifdef NIU_NAPI_STRUCT + struct napi_struct napi; +#else + struct net_device *dummy_netdev; +#endif + struct niu *np; + u8 ldg_num; + u8 timer; + u64 v0, v1, v2; + unsigned int irq; +}; + +struct niu_xmac_stats { + u64 tx_frames; + u64 tx_bytes; + u64 tx_fifo_errors; + u64 tx_overflow_errors; + u64 tx_max_pkt_size_errors; + u64 tx_underflow_errors; + + u64 rx_local_faults; + u64 rx_remote_faults; + u64 rx_link_faults; + u64 rx_align_errors; + u64 rx_frags; + u64 rx_mcasts; + u64 rx_bcasts; + u64 rx_hist_cnt1; + u64 rx_hist_cnt2; + u64 rx_hist_cnt3; + u64 rx_hist_cnt4; + u64 rx_hist_cnt5; + u64 rx_hist_cnt6; + u64 rx_hist_cnt7; + u64 rx_octets; + u64 rx_code_violations; + u64 rx_len_errors; + u64 rx_crc_errors; + u64 rx_underflows; + u64 rx_overflows; + + u64 pause_off_state; + u64 pause_on_state; + u64 pause_received; +}; + +struct niu_bmac_stats { + u64 tx_underflow_errors; + u64 tx_max_pkt_size_errors; + u64 tx_bytes; + u64 tx_frames; + + u64 rx_overflows; + u64 rx_frames; + u64 rx_align_errors; + u64 rx_crc_errors; + u64 rx_len_errors; + + u64 pause_off_state; + u64 pause_on_state; + u64 pause_received; +}; + +union niu_mac_stats { + struct niu_xmac_stats xmac; + struct niu_bmac_stats bmac; +}; + +struct niu_phy_ops { + int (*serdes_init)(struct niu *np); + int (*xcvr_init)(struct niu *np); + int (*link_status)(struct niu *np, int *); +}; + +struct of_device; +struct niu { + void __iomem *regs; + struct net_device *dev; + struct pci_dev *pdev; + struct device *device; + struct niu_parent *parent; + + u32 flags; +#define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ +#define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ +#define NIU_FLAGS_PROMISC 0x00100000 /* PROMISC enabled */ +#define NIU_FLAGS_VPD_VALID 0x00080000 /* VPD has valid version */ +#define NIU_FLAGS_10G 0x00040000 /* 0=1G 1=10G */ +#define NIU_FLAGS_FIBER 0x00020000 /* 0=COPPER 1=FIBER */ +#define NIU_FLAGS_XMAC 0x00010000 /* 0=BMAC 1=XMAC */ + + u32 msg_enable; + + /* Protects hw programming, and ring state. */ + spinlock_t lock; + + const struct niu_ops *ops; + struct net_device_stats net_stats; + union niu_mac_stats mac_stats; + + struct rx_ring_info *rx_rings; + struct tx_ring_info *tx_rings; + int num_rx_rings; + int num_tx_rings; + + struct niu_ldg ldg[NIU_NUM_LDG]; + int num_ldg; + + void __iomem *mac_regs; + unsigned long ipp_off; + unsigned long pcs_off; + unsigned long xpcs_off; + + struct timer_list timer; + const struct niu_phy_ops *phy_ops; + int phy_addr; + + struct niu_link_config link_config; + + struct work_struct reset_task; + + u8 port; + u8 mac_xcvr; +#define MAC_XCVR_MII 1 +#define MAC_XCVR_PCS 2 +#define MAC_XCVR_XPCS 3 + + struct niu_classifier clas; + + struct niu_vpd vpd; + u32 eeprom_len; + + struct of_device *op; + void __iomem *vir_regs_1; + void __iomem *vir_regs_2; +}; + +#endif /* _NIU_H */ --- linux-source-2.6.22-2.6.22.orig/drivers/net/sunvnet.c +++ linux-source-2.6.22-2.6.22/drivers/net/sunvnet.c @@ -0,0 +1,1295 @@ +/* sunvnet.c: Sun LDOM Virtual Network Driver. + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sunvnet.h" + +#define DRV_MODULE_NAME "sunvnet" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "June 25, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("Sun LDOM virtual network driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +/* Ordered from largest major to lowest */ +static struct vio_version vnet_versions[] = { + { .major = 1, .minor = 0 }, +}; + +static inline u32 vnet_tx_dring_avail(struct vio_dring_state *dr) +{ + return vio_dring_avail(dr, VNET_TX_RING_SIZE); +} + +static int vnet_handle_unknown(struct vnet_port *port, void *arg) +{ + struct vio_msg_tag *pkt = arg; + + printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n", + pkt->type, pkt->stype, pkt->stype_env, pkt->sid); + printk(KERN_ERR PFX "Resetting connection.\n"); + + ldc_disconnect(port->vio.lp); + + return -ECONNRESET; +} + +static int vnet_send_attr(struct vio_driver_state *vio) +{ + struct vnet_port *port = to_vnet_port(vio); + struct net_device *dev = port->vp->dev; + struct vio_net_attr_info pkt; + int i; + + memset(&pkt, 0, sizeof(pkt)); + pkt.tag.type = VIO_TYPE_CTRL; + pkt.tag.stype = VIO_SUBTYPE_INFO; + pkt.tag.stype_env = VIO_ATTR_INFO; + pkt.tag.sid = vio_send_sid(vio); + pkt.xfer_mode = VIO_DRING_MODE; + pkt.addr_type = VNET_ADDR_ETHERMAC; + pkt.ack_freq = 0; + for (i = 0; i < 6; i++) + pkt.addr |= (u64)dev->dev_addr[i] << ((5 - i) * 8); + pkt.mtu = ETH_FRAME_LEN; + + viodbg(HS, "SEND NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] " + "ackfreq[%u] mtu[%llu]\n", + pkt.xfer_mode, pkt.addr_type, + (unsigned long long) pkt.addr, + pkt.ack_freq, + (unsigned long long) pkt.mtu); + + return vio_ldc_send(vio, &pkt, sizeof(pkt)); +} + +static int handle_attr_info(struct vio_driver_state *vio, + struct vio_net_attr_info *pkt) +{ + viodbg(HS, "GOT NET ATTR INFO xmode[0x%x] atype[0x%x] addr[%llx] " + "ackfreq[%u] mtu[%llu]\n", + pkt->xfer_mode, pkt->addr_type, + (unsigned long long) pkt->addr, + pkt->ack_freq, + (unsigned long long) pkt->mtu); + + pkt->tag.sid = vio_send_sid(vio); + + if (pkt->xfer_mode != VIO_DRING_MODE || + pkt->addr_type != VNET_ADDR_ETHERMAC || + pkt->mtu != ETH_FRAME_LEN) { + viodbg(HS, "SEND NET ATTR NACK\n"); + + pkt->tag.stype = VIO_SUBTYPE_NACK; + + (void) vio_ldc_send(vio, pkt, sizeof(*pkt)); + + return -ECONNRESET; + } else { + viodbg(HS, "SEND NET ATTR ACK\n"); + + pkt->tag.stype = VIO_SUBTYPE_ACK; + + return vio_ldc_send(vio, pkt, sizeof(*pkt)); + } + +} + +static int handle_attr_ack(struct vio_driver_state *vio, + struct vio_net_attr_info *pkt) +{ + viodbg(HS, "GOT NET ATTR ACK\n"); + + return 0; +} + +static int handle_attr_nack(struct vio_driver_state *vio, + struct vio_net_attr_info *pkt) +{ + viodbg(HS, "GOT NET ATTR NACK\n"); + + return -ECONNRESET; +} + +static int vnet_handle_attr(struct vio_driver_state *vio, void *arg) +{ + struct vio_net_attr_info *pkt = arg; + + switch (pkt->tag.stype) { + case VIO_SUBTYPE_INFO: + return handle_attr_info(vio, pkt); + + case VIO_SUBTYPE_ACK: + return handle_attr_ack(vio, pkt); + + case VIO_SUBTYPE_NACK: + return handle_attr_nack(vio, pkt); + + default: + return -ECONNRESET; + } +} + +static void vnet_handshake_complete(struct vio_driver_state *vio) +{ + struct vio_dring_state *dr; + + dr = &vio->drings[VIO_DRIVER_RX_RING]; + dr->snd_nxt = dr->rcv_nxt = 1; + + dr = &vio->drings[VIO_DRIVER_TX_RING]; + dr->snd_nxt = dr->rcv_nxt = 1; +} + +/* The hypervisor interface that implements copying to/from imported + * memory from another domain requires that copies are done to 8-byte + * aligned buffers, and that the lengths of such copies are also 8-byte + * multiples. + * + * So we align skb->data to an 8-byte multiple and pad-out the data + * area so we can round the copy length up to the next multiple of + * 8 for the copy. + * + * The transmitter puts the actual start of the packet 6 bytes into + * the buffer it sends over, so that the IP headers after the ethernet + * header are aligned properly. These 6 bytes are not in the descriptor + * length, they are simply implied. This offset is represented using + * the VNET_PACKET_SKIP macro. + */ +static struct sk_buff *alloc_and_align_skb(struct net_device *dev, + unsigned int len) +{ + struct sk_buff *skb = netdev_alloc_skb(dev, len+VNET_PACKET_SKIP+8+8); + unsigned long addr, off; + + if (unlikely(!skb)) + return NULL; + + addr = (unsigned long) skb->data; + off = ((addr + 7UL) & ~7UL) - addr; + if (off) + skb_reserve(skb, off); + + return skb; +} + +static int vnet_rx_one(struct vnet_port *port, unsigned int len, + struct ldc_trans_cookie *cookies, int ncookies) +{ + struct net_device *dev = port->vp->dev; + unsigned int copy_len; + struct sk_buff *skb; + int err; + + err = -EMSGSIZE; + if (unlikely(len < ETH_ZLEN || len > ETH_FRAME_LEN)) { + dev->stats.rx_length_errors++; + goto out_dropped; + } + + skb = alloc_and_align_skb(dev, len); + err = -ENOMEM; + if (unlikely(!skb)) { + dev->stats.rx_missed_errors++; + goto out_dropped; + } + + copy_len = (len + VNET_PACKET_SKIP + 7U) & ~7U; + skb_put(skb, copy_len); + err = ldc_copy(port->vio.lp, LDC_COPY_IN, + skb->data, copy_len, 0, + cookies, ncookies); + if (unlikely(err < 0)) { + dev->stats.rx_frame_errors++; + goto out_free_skb; + } + + skb_pull(skb, VNET_PACKET_SKIP); + skb_trim(skb, len); + skb->protocol = eth_type_trans(skb, dev); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; + + netif_rx(skb); + + return 0; + +out_free_skb: + kfree_skb(skb); + +out_dropped: + dev->stats.rx_dropped++; + return err; +} + +static int vnet_send_ack(struct vnet_port *port, struct vio_dring_state *dr, + u32 start, u32 end, u8 vio_dring_state) +{ + struct vio_dring_data hdr = { + .tag = { + .type = VIO_TYPE_DATA, + .stype = VIO_SUBTYPE_ACK, + .stype_env = VIO_DRING_DATA, + .sid = vio_send_sid(&port->vio), + }, + .dring_ident = dr->ident, + .start_idx = start, + .end_idx = end, + .state = vio_dring_state, + }; + int err, delay; + + hdr.seq = dr->snd_nxt; + delay = 1; + do { + err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr)); + if (err > 0) { + dr->snd_nxt++; + break; + } + udelay(delay); + if ((delay <<= 1) > 128) + delay = 128; + } while (err == -EAGAIN); + + return err; +} + +static u32 next_idx(u32 idx, struct vio_dring_state *dr) +{ + if (++idx == dr->num_entries) + idx = 0; + return idx; +} + +static u32 prev_idx(u32 idx, struct vio_dring_state *dr) +{ + if (idx == 0) + idx = dr->num_entries - 1; + else + idx--; + + return idx; +} + +static struct vio_net_desc *get_rx_desc(struct vnet_port *port, + struct vio_dring_state *dr, + u32 index) +{ + struct vio_net_desc *desc = port->vio.desc_buf; + int err; + + err = ldc_get_dring_entry(port->vio.lp, desc, dr->entry_size, + (index * dr->entry_size), + dr->cookies, dr->ncookies); + if (err < 0) + return ERR_PTR(err); + + return desc; +} + +static int put_rx_desc(struct vnet_port *port, + struct vio_dring_state *dr, + struct vio_net_desc *desc, + u32 index) +{ + int err; + + err = ldc_put_dring_entry(port->vio.lp, desc, dr->entry_size, + (index * dr->entry_size), + dr->cookies, dr->ncookies); + if (err < 0) + return err; + + return 0; +} + +static int vnet_walk_rx_one(struct vnet_port *port, + struct vio_dring_state *dr, + u32 index, int *needs_ack) +{ + struct vio_net_desc *desc = get_rx_desc(port, dr, index); + struct vio_driver_state *vio = &port->vio; + int err; + + if (IS_ERR(desc)) + return PTR_ERR(desc); + + viodbg(DATA, "vio_walk_rx_one desc[%02x:%02x:%08x:%08x:%lx:%lx]\n", + desc->hdr.state, desc->hdr.ack, + desc->size, desc->ncookies, + desc->cookies[0].cookie_addr, + desc->cookies[0].cookie_size); + + if (desc->hdr.state != VIO_DESC_READY) + return 1; + err = vnet_rx_one(port, desc->size, desc->cookies, desc->ncookies); + if (err == -ECONNRESET) + return err; + desc->hdr.state = VIO_DESC_DONE; + err = put_rx_desc(port, dr, desc, index); + if (err < 0) + return err; + *needs_ack = desc->hdr.ack; + return 0; +} + +static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, + u32 start, u32 end) +{ + struct vio_driver_state *vio = &port->vio; + int ack_start = -1, ack_end = -1; + + end = (end == (u32) -1) ? prev_idx(start, dr) : next_idx(end, dr); + + viodbg(DATA, "vnet_walk_rx start[%08x] end[%08x]\n", start, end); + + while (start != end) { + int ack = 0, err = vnet_walk_rx_one(port, dr, start, &ack); + if (err == -ECONNRESET) + return err; + if (err != 0) + break; + if (ack_start == -1) + ack_start = start; + ack_end = start; + start = next_idx(start, dr); + if (ack && start != end) { + err = vnet_send_ack(port, dr, ack_start, ack_end, + VIO_DRING_ACTIVE); + if (err == -ECONNRESET) + return err; + ack_start = -1; + } + } + if (unlikely(ack_start == -1)) + ack_start = ack_end = prev_idx(start, dr); + return vnet_send_ack(port, dr, ack_start, ack_end, VIO_DRING_STOPPED); +} + +static int vnet_rx(struct vnet_port *port, void *msgbuf) +{ + struct vio_dring_data *pkt = msgbuf; + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_RX_RING]; + struct vio_driver_state *vio = &port->vio; + + viodbg(DATA, "vnet_rx stype_env[%04x] seq[%016lx] rcv_nxt[%016lx]\n", + pkt->tag.stype_env, pkt->seq, dr->rcv_nxt); + + if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) + return 0; + if (unlikely(pkt->seq != dr->rcv_nxt)) { + printk(KERN_ERR PFX "RX out of sequence seq[0x%lx] " + "rcv_nxt[0x%lx]\n", pkt->seq, dr->rcv_nxt); + return 0; + } + + dr->rcv_nxt++; + + /* XXX Validate pkt->start_idx and pkt->end_idx XXX */ + + return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx); +} + +static int idx_is_pending(struct vio_dring_state *dr, u32 end) +{ + u32 idx = dr->cons; + int found = 0; + + while (idx != dr->prod) { + if (idx == end) { + found = 1; + break; + } + idx = next_idx(idx, dr); + } + return found; +} + +static int vnet_ack(struct vnet_port *port, void *msgbuf) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + struct vio_dring_data *pkt = msgbuf; + struct net_device *dev; + struct vnet *vp; + u32 end; + + if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) + return 0; + + end = pkt->end_idx; + if (unlikely(!idx_is_pending(dr, end))) + return 0; + + dr->cons = next_idx(end, dr); + + vp = port->vp; + dev = vp->dev; + if (unlikely(netif_queue_stopped(dev) && + vnet_tx_dring_avail(dr) >= VNET_TX_WAKEUP_THRESH(dr))) + return 1; + + return 0; +} + +static int vnet_nack(struct vnet_port *port, void *msgbuf) +{ + /* XXX just reset or similar XXX */ + return 0; +} + +static int handle_mcast(struct vnet_port *port, void *msgbuf) +{ + struct vio_net_mcast_info *pkt = msgbuf; + + if (pkt->tag.stype != VIO_SUBTYPE_ACK) + printk(KERN_ERR PFX "%s: Got unexpected MCAST reply " + "[%02x:%02x:%04x:%08x]\n", + port->vp->dev->name, + pkt->tag.type, + pkt->tag.stype, + pkt->tag.stype_env, + pkt->tag.sid); + + return 0; +} + +static void maybe_tx_wakeup(struct vnet *vp) +{ + struct net_device *dev = vp->dev; + + netif_tx_lock(dev); + if (likely(netif_queue_stopped(dev))) { + struct vnet_port *port; + int wake = 1; + + list_for_each_entry(port, &vp->port_list, list) { + struct vio_dring_state *dr; + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + if (vnet_tx_dring_avail(dr) < + VNET_TX_WAKEUP_THRESH(dr)) { + wake = 0; + break; + } + } + if (wake) + netif_wake_queue(dev); + } + netif_tx_unlock(dev); +} + +static void vnet_event(void *arg, int event) +{ + struct vnet_port *port = arg; + struct vio_driver_state *vio = &port->vio; + unsigned long flags; + int tx_wakeup, err; + + spin_lock_irqsave(&vio->lock, flags); + + if (unlikely(event == LDC_EVENT_RESET || + event == LDC_EVENT_UP)) { + vio_link_state_change(vio, event); + spin_unlock_irqrestore(&vio->lock, flags); + + if (event == LDC_EVENT_RESET) + vio_port_up(vio); + return; + } + + if (unlikely(event != LDC_EVENT_DATA_READY)) { + printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); + spin_unlock_irqrestore(&vio->lock, flags); + return; + } + + tx_wakeup = err = 0; + while (1) { + union { + struct vio_msg_tag tag; + u64 raw[8]; + } msgbuf; + + err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf)); + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + vio_conn_reset(vio); + break; + } + if (err == 0) + break; + viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n", + msgbuf.tag.type, + msgbuf.tag.stype, + msgbuf.tag.stype_env, + msgbuf.tag.sid); + err = vio_validate_sid(vio, &msgbuf.tag); + if (err < 0) + break; + + if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) { + if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) { + err = vnet_rx(port, &msgbuf); + } else if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) { + err = vnet_ack(port, &msgbuf); + if (err > 0) + tx_wakeup |= err; + } else if (msgbuf.tag.stype == VIO_SUBTYPE_NACK) { + err = vnet_nack(port, &msgbuf); + } + } else if (msgbuf.tag.type == VIO_TYPE_CTRL) { + if (msgbuf.tag.stype_env == VNET_MCAST_INFO) + err = handle_mcast(port, &msgbuf); + else + err = vio_control_pkt_engine(vio, &msgbuf); + if (err) + break; + } else { + err = vnet_handle_unknown(port, &msgbuf); + } + if (err == -ECONNRESET) + break; + } + spin_unlock(&vio->lock); + if (unlikely(tx_wakeup && err != -ECONNRESET)) + maybe_tx_wakeup(port->vp); + local_irq_restore(flags); +} + +static int __vnet_tx_trigger(struct vnet_port *port) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + struct vio_dring_data hdr = { + .tag = { + .type = VIO_TYPE_DATA, + .stype = VIO_SUBTYPE_INFO, + .stype_env = VIO_DRING_DATA, + .sid = vio_send_sid(&port->vio), + }, + .dring_ident = dr->ident, + .start_idx = dr->prod, + .end_idx = (u32) -1, + }; + int err, delay; + + hdr.seq = dr->snd_nxt; + delay = 1; + do { + err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr)); + if (err > 0) { + dr->snd_nxt++; + break; + } + udelay(delay); + if ((delay <<= 1) > 128) + delay = 128; + } while (err == -EAGAIN); + + return err; +} + +struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) +{ + unsigned int hash = vnet_hashfn(skb->data); + struct hlist_head *hp = &vp->port_hash[hash]; + struct hlist_node *n; + struct vnet_port *port; + + hlist_for_each_entry(port, n, hp, hash) { + if (!compare_ether_addr(port->raddr, skb->data)) + return port; + } + port = NULL; + if (!list_empty(&vp->port_list)) + port = list_entry(vp->port_list.next, struct vnet_port, list); + + return port; +} + +struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb) +{ + struct vnet_port *ret; + unsigned long flags; + + spin_lock_irqsave(&vp->lock, flags); + ret = __tx_port_find(vp, skb); + spin_unlock_irqrestore(&vp->lock, flags); + + return ret; +} + +static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct vnet *vp = netdev_priv(dev); + struct vnet_port *port = tx_port_find(vp, skb); + struct vio_dring_state *dr; + struct vio_net_desc *d; + unsigned long flags; + unsigned int len; + void *tx_buf; + int i, err; + + if (unlikely(!port)) + goto out_dropped; + + spin_lock_irqsave(&port->vio.lock, flags); + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + if (unlikely(vnet_tx_dring_avail(dr) < 2)) { + if (!netif_queue_stopped(dev)) { + netif_stop_queue(dev); + + /* This is a hard error, log it. */ + printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " + "queue awake!\n", dev->name); + dev->stats.tx_errors++; + } + spin_unlock_irqrestore(&port->vio.lock, flags); + return NETDEV_TX_BUSY; + } + + d = vio_dring_cur(dr); + + tx_buf = port->tx_bufs[dr->prod].buf; + skb_copy_from_linear_data(skb, tx_buf + VNET_PACKET_SKIP, skb->len); + + len = skb->len; + if (len < ETH_ZLEN) { + len = ETH_ZLEN; + memset(tx_buf+VNET_PACKET_SKIP+skb->len, 0, len - skb->len); + } + + d->hdr.ack = VIO_ACK_ENABLE; + d->size = len; + d->ncookies = port->tx_bufs[dr->prod].ncookies; + for (i = 0; i < d->ncookies; i++) + d->cookies[i] = port->tx_bufs[dr->prod].cookies[i]; + + /* This has to be a non-SMP write barrier because we are writing + * to memory which is shared with the peer LDOM. + */ + wmb(); + + d->hdr.state = VIO_DESC_READY; + + err = __vnet_tx_trigger(port); + if (unlikely(err < 0)) { + printk(KERN_INFO PFX "%s: TX trigger error %d\n", + dev->name, err); + d->hdr.state = VIO_DESC_FREE; + dev->stats.tx_carrier_errors++; + goto out_dropped_unlock; + } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1); + if (unlikely(vnet_tx_dring_avail(dr) < 2)) { + netif_stop_queue(dev); + if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr)) + netif_wake_queue(dev); + } + + spin_unlock_irqrestore(&port->vio.lock, flags); + + dev_kfree_skb(skb); + + dev->trans_start = jiffies; + return NETDEV_TX_OK; + +out_dropped_unlock: + spin_unlock_irqrestore(&port->vio.lock, flags); + +out_dropped: + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; +} + +static void vnet_tx_timeout(struct net_device *dev) +{ + /* XXX Implement me XXX */ +} + +static int vnet_open(struct net_device *dev) +{ + netif_carrier_on(dev); + netif_start_queue(dev); + + return 0; +} + +static int vnet_close(struct net_device *dev) +{ + netif_stop_queue(dev); + netif_carrier_off(dev); + + return 0; +} + +static struct vnet_mcast_entry *__vnet_mc_find(struct vnet *vp, u8 *addr) +{ + struct vnet_mcast_entry *m; + + for (m = vp->mcast_list; m; m = m->next) { + if (!memcmp(m->addr, addr, ETH_ALEN)) + return m; + } + return NULL; +} + +static void __update_mc_list(struct vnet *vp, struct net_device *dev) +{ + struct dev_mc_list *p; + + for (p = dev->mc_list; p; p = p->next) { + struct vnet_mcast_entry *m; + + m = __vnet_mc_find(vp, p->dmi_addr); + if (m) { + m->hit = 1; + continue; + } + + if (!m) { + m = kzalloc(sizeof(*m), GFP_ATOMIC); + if (!m) + continue; + memcpy(m->addr, p->dmi_addr, ETH_ALEN); + m->hit = 1; + + m->next = vp->mcast_list; + vp->mcast_list = m; + } + } +} + +static void __send_mc_list(struct vnet *vp, struct vnet_port *port) +{ + struct vio_net_mcast_info info; + struct vnet_mcast_entry *m, **pp; + int n_addrs; + + memset(&info, 0, sizeof(info)); + + info.tag.type = VIO_TYPE_CTRL; + info.tag.stype = VIO_SUBTYPE_INFO; + info.tag.stype_env = VNET_MCAST_INFO; + info.tag.sid = vio_send_sid(&port->vio); + info.set = 1; + + n_addrs = 0; + for (m = vp->mcast_list; m; m = m->next) { + if (m->sent) + continue; + m->sent = 1; + memcpy(&info.mcast_addr[n_addrs * ETH_ALEN], + m->addr, ETH_ALEN); + if (++n_addrs == VNET_NUM_MCAST) { + info.count = n_addrs; + + (void) vio_ldc_send(&port->vio, &info, + sizeof(info)); + n_addrs = 0; + } + } + if (n_addrs) { + info.count = n_addrs; + (void) vio_ldc_send(&port->vio, &info, sizeof(info)); + } + + info.set = 0; + + n_addrs = 0; + pp = &vp->mcast_list; + while ((m = *pp) != NULL) { + if (m->hit) { + m->hit = 0; + pp = &m->next; + continue; + } + + memcpy(&info.mcast_addr[n_addrs * ETH_ALEN], + m->addr, ETH_ALEN); + if (++n_addrs == VNET_NUM_MCAST) { + info.count = n_addrs; + (void) vio_ldc_send(&port->vio, &info, + sizeof(info)); + n_addrs = 0; + } + + *pp = m->next; + kfree(m); + } + if (n_addrs) { + info.count = n_addrs; + (void) vio_ldc_send(&port->vio, &info, sizeof(info)); + } +} + +static void vnet_set_rx_mode(struct net_device *dev) +{ + struct vnet *vp = netdev_priv(dev); + struct vnet_port *port; + unsigned long flags; + + spin_lock_irqsave(&vp->lock, flags); + if (!list_empty(&vp->port_list)) { + port = list_entry(vp->port_list.next, struct vnet_port, list); + + if (port->switch_port) { + __update_mc_list(vp, dev); + __send_mc_list(vp, port); + } + } + spin_unlock_irqrestore(&vp->lock, flags); +} + +static int vnet_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu != ETH_DATA_LEN) + return -EINVAL; + + dev->mtu = new_mtu; + return 0; +} + +static int vnet_set_mac_addr(struct net_device *dev, void *p) +{ + return -EINVAL; +} + +static void vnet_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); +} + +static u32 vnet_get_msglevel(struct net_device *dev) +{ + struct vnet *vp = netdev_priv(dev); + return vp->msg_enable; +} + +static void vnet_set_msglevel(struct net_device *dev, u32 value) +{ + struct vnet *vp = netdev_priv(dev); + vp->msg_enable = value; +} + +static const struct ethtool_ops vnet_ethtool_ops = { + .get_drvinfo = vnet_get_drvinfo, + .get_msglevel = vnet_get_msglevel, + .set_msglevel = vnet_set_msglevel, + .get_link = ethtool_op_get_link, + .get_perm_addr = ethtool_op_get_perm_addr, +}; + +static void vnet_port_free_tx_bufs(struct vnet_port *port) +{ + struct vio_dring_state *dr; + int i; + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + if (dr->base) { + ldc_free_exp_dring(port->vio.lp, dr->base, + (dr->entry_size * dr->num_entries), + dr->cookies, dr->ncookies); + dr->base = NULL; + dr->entry_size = 0; + dr->num_entries = 0; + dr->pending = 0; + dr->ncookies = 0; + } + + for (i = 0; i < VNET_TX_RING_SIZE; i++) { + void *buf = port->tx_bufs[i].buf; + + if (!buf) + continue; + + ldc_unmap(port->vio.lp, + port->tx_bufs[i].cookies, + port->tx_bufs[i].ncookies); + + kfree(buf); + port->tx_bufs[i].buf = NULL; + } +} + +static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port) +{ + struct vio_dring_state *dr; + unsigned long len; + int i, err, ncookies; + void *dring; + + for (i = 0; i < VNET_TX_RING_SIZE; i++) { + void *buf = kzalloc(ETH_FRAME_LEN + 8, GFP_KERNEL); + int map_len = (ETH_FRAME_LEN + 7) & ~7; + + err = -ENOMEM; + if (!buf) { + printk(KERN_ERR "TX buffer allocation failure\n"); + goto err_out; + } + err = -EFAULT; + if ((unsigned long)buf & (8UL - 1)) { + printk(KERN_ERR "TX buffer misaligned\n"); + kfree(buf); + goto err_out; + } + + err = ldc_map_single(port->vio.lp, buf, map_len, + port->tx_bufs[i].cookies, 2, + (LDC_MAP_SHADOW | + LDC_MAP_DIRECT | + LDC_MAP_RW)); + if (err < 0) { + kfree(buf); + goto err_out; + } + port->tx_bufs[i].buf = buf; + port->tx_bufs[i].ncookies = err; + } + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + + len = (VNET_TX_RING_SIZE * + (sizeof(struct vio_net_desc) + + (sizeof(struct ldc_trans_cookie) * 2))); + + ncookies = VIO_MAX_RING_COOKIES; + dring = ldc_alloc_exp_dring(port->vio.lp, len, + dr->cookies, &ncookies, + (LDC_MAP_SHADOW | + LDC_MAP_DIRECT | + LDC_MAP_RW)); + if (IS_ERR(dring)) { + err = PTR_ERR(dring); + goto err_out; + } + + dr->base = dring; + dr->entry_size = (sizeof(struct vio_net_desc) + + (sizeof(struct ldc_trans_cookie) * 2)); + dr->num_entries = VNET_TX_RING_SIZE; + dr->prod = dr->cons = 0; + dr->pending = VNET_TX_RING_SIZE; + dr->ncookies = ncookies; + + return 0; + +err_out: + vnet_port_free_tx_bufs(port); + + return err; +} + +static LIST_HEAD(vnet_list); +static DEFINE_MUTEX(vnet_list_mutex); + +static struct vnet * __devinit vnet_new(const u64 *local_mac) +{ + struct net_device *dev; + struct vnet *vp; + int err, i; + + dev = alloc_etherdev(sizeof(*vp)); + if (!dev) { + printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + return ERR_PTR(-ENOMEM); + } + + for (i = 0; i < ETH_ALEN; i++) + dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff; + + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); + + vp = netdev_priv(dev); + + spin_lock_init(&vp->lock); + vp->dev = dev; + + INIT_LIST_HEAD(&vp->port_list); + for (i = 0; i < VNET_PORT_HASH_SIZE; i++) + INIT_HLIST_HEAD(&vp->port_hash[i]); + INIT_LIST_HEAD(&vp->list); + vp->local_mac = *local_mac; + + dev->open = vnet_open; + dev->stop = vnet_close; + dev->set_multicast_list = vnet_set_rx_mode; + dev->set_mac_address = vnet_set_mac_addr; + dev->tx_timeout = vnet_tx_timeout; + dev->ethtool_ops = &vnet_ethtool_ops; + dev->watchdog_timeo = VNET_TX_TIMEOUT; + dev->change_mtu = vnet_change_mtu; + dev->hard_start_xmit = vnet_start_xmit; + + err = register_netdev(dev); + if (err) { + printk(KERN_ERR PFX "Cannot register net device, " + "aborting.\n"); + goto err_out_free_dev; + } + + printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name); + + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + + list_add(&vp->list, &vnet_list); + + return vp; + +err_out_free_dev: + free_netdev(dev); + + return ERR_PTR(err); +} + +static struct vnet * __devinit vnet_find_or_create(const u64 *local_mac) +{ + struct vnet *iter, *vp; + + mutex_lock(&vnet_list_mutex); + vp = NULL; + list_for_each_entry(iter, &vnet_list, list) { + if (iter->local_mac == *local_mac) { + vp = iter; + break; + } + } + if (!vp) + vp = vnet_new(local_mac); + mutex_unlock(&vnet_list_mutex); + + return vp; +} + +static const char *local_mac_prop = "local-mac-address"; + +static struct vnet * __devinit vnet_find_parent(struct mdesc_handle *hp, + u64 port_node) +{ + const u64 *local_mac = NULL; + u64 a; + + mdesc_for_each_arc(a, hp, port_node, MDESC_ARC_TYPE_BACK) { + u64 target = mdesc_arc_target(hp, a); + const char *name; + + name = mdesc_get_property(hp, target, "name", NULL); + if (!name || strcmp(name, "network")) + continue; + + local_mac = mdesc_get_property(hp, target, + local_mac_prop, NULL); + if (local_mac) + break; + } + if (!local_mac) + return ERR_PTR(-ENODEV); + + return vnet_find_or_create(local_mac); +} + +static struct ldc_channel_config vnet_ldc_cfg = { + .event = vnet_event, + .mtu = 64, + .mode = LDC_MODE_UNRELIABLE, +}; + +static struct vio_driver_ops vnet_vio_ops = { + .send_attr = vnet_send_attr, + .handle_attr = vnet_handle_attr, + .handshake_complete = vnet_handshake_complete, +}; + +static void print_version(void) +{ + static int version_printed; + + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); +} + +const char *remote_macaddr_prop = "remote-mac-address"; + +static int __devinit vnet_port_probe(struct vio_dev *vdev, + const struct vio_device_id *id) +{ + struct mdesc_handle *hp; + struct vnet_port *port; + unsigned long flags; + struct vnet *vp; + const u64 *rmac; + int len, i, err, switch_port; + + print_version(); + + hp = mdesc_grab(); + + vp = vnet_find_parent(hp, vdev->mp); + if (IS_ERR(vp)) { + printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); + err = PTR_ERR(vp); + goto err_out_put_mdesc; + } + + rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); + err = -ENODEV; + if (!rmac) { + printk(KERN_ERR PFX "Port lacks %s property.\n", + remote_macaddr_prop); + goto err_out_put_mdesc; + } + + port = kzalloc(sizeof(*port), GFP_KERNEL); + err = -ENOMEM; + if (!port) { + printk(KERN_ERR PFX "Cannot allocate vnet_port.\n"); + goto err_out_put_mdesc; + } + + for (i = 0; i < ETH_ALEN; i++) + port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff; + + port->vp = vp; + + err = vio_driver_init(&port->vio, vdev, VDEV_NETWORK, + vnet_versions, ARRAY_SIZE(vnet_versions), + &vnet_vio_ops, vp->dev->name); + if (err) + goto err_out_free_port; + + err = vio_ldc_alloc(&port->vio, &vnet_ldc_cfg, port); + if (err) + goto err_out_free_port; + + err = vnet_port_alloc_tx_bufs(port); + if (err) + goto err_out_free_ldc; + + INIT_HLIST_NODE(&port->hash); + INIT_LIST_HEAD(&port->list); + + switch_port = 0; + if (mdesc_get_property(hp, vdev->mp, "switch-port", NULL) != NULL) + switch_port = 1; + port->switch_port = switch_port; + + spin_lock_irqsave(&vp->lock, flags); + if (switch_port) + list_add(&port->list, &vp->port_list); + else + list_add_tail(&port->list, &vp->port_list); + hlist_add_head(&port->hash, &vp->port_hash[vnet_hashfn(port->raddr)]); + spin_unlock_irqrestore(&vp->lock, flags); + + dev_set_drvdata(&vdev->dev, port); + + printk(KERN_INFO "%s: PORT ( remote-mac ", vp->dev->name); + for (i = 0; i < 6; i++) + printk("%2.2x%c", port->raddr[i], i == 5 ? ' ' : ':'); + if (switch_port) + printk("switch-port "); + printk(")\n"); + + vio_port_up(&port->vio); + + mdesc_release(hp); + + return 0; + +err_out_free_ldc: + vio_ldc_free(&port->vio); + +err_out_free_port: + kfree(port); + +err_out_put_mdesc: + mdesc_release(hp); + return err; +} + +static int vnet_port_remove(struct vio_dev *vdev) +{ + struct vnet_port *port = dev_get_drvdata(&vdev->dev); + + if (port) { + struct vnet *vp = port->vp; + unsigned long flags; + + del_timer_sync(&port->vio.timer); + + spin_lock_irqsave(&vp->lock, flags); + list_del(&port->list); + hlist_del(&port->hash); + spin_unlock_irqrestore(&vp->lock, flags); + + vnet_port_free_tx_bufs(port); + vio_ldc_free(&port->vio); + + dev_set_drvdata(&vdev->dev, NULL); + + kfree(port); + } + return 0; +} + +static struct vio_device_id vnet_port_match[] = { + { + .type = "vnet-port", + }, + {}, +}; +MODULE_DEVICE_TABLE(vio, vnet_port_match); + +static struct vio_driver vnet_port_driver = { + .id_table = vnet_port_match, + .probe = vnet_port_probe, + .remove = vnet_port_remove, + .driver = { + .name = "vnet_port", + .owner = THIS_MODULE, + } +}; + +static int __init vnet_init(void) +{ + return vio_register_driver(&vnet_port_driver); +} + +static void __exit vnet_exit(void) +{ + vio_unregister_driver(&vnet_port_driver); +} + +module_init(vnet_init); +module_exit(vnet_exit); --- linux-source-2.6.22-2.6.22.orig/drivers/net/slip.c +++ linux-source-2.6.22-2.6.22/drivers/net/slip.c @@ -463,9 +463,14 @@ /* 20 sec timeout not reached */ goto out; } - printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + { + int cib = 0; + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); + printk(KERN_WARNING "%s: transmit timed out, %s?\n", + dev->name, (cib || sl->xleft) ? + "bad line quality" : "driver error"); + } sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); sl_unlock(sl); @@ -836,6 +841,8 @@ if(!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; /* RTnetlink lock is misused here to serialize concurrent opens of slip channels. There are better ways, but it is --- linux-source-2.6.22-2.6.22.orig/drivers/net/niu.c +++ linux-source-2.6.22-2.6.22/drivers/net/niu.c @@ -0,0 +1,8005 @@ +/* niu.c: Neptune ethernet driver. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_SPARC64 +#include +#include +#endif + +#include "niu.h" + +#define DRV_MODULE_NAME "niu" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "0.5" +#define DRV_MODULE_RELDATE "October 5, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("NIU ethernet driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +#ifndef DMA_44BIT_MASK +#define DMA_44BIT_MASK 0x00000fffffffffffULL +#endif + +#ifndef readq +static u64 readq(void __iomem *reg) +{ + return (((u64)readl(reg + 0x4UL) << 32) | + (u64)readl(reg)); +} + +static void writeq(u64 val, void __iomem *reg) +{ + writel(val & 0xffffffff, reg); + writel(val >> 32, reg + 0x4UL); +} +#endif + +static struct pci_device_id niu_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_SUN, 0xabcd)}, + {} +}; + +MODULE_DEVICE_TABLE(pci, niu_pci_tbl); + +#define NIU_TX_TIMEOUT (5 * HZ) + +#define nr64(reg) readq(np->regs + (reg)) +#define nw64(reg, val) writeq((val), np->regs + (reg)) + +#define nr64_mac(reg) readq(np->mac_regs + (reg)) +#define nw64_mac(reg, val) writeq((val), np->mac_regs + (reg)) + +#define nr64_ipp(reg) readq(np->regs + np->ipp_off + (reg)) +#define nw64_ipp(reg, val) writeq((val), np->regs + np->ipp_off + (reg)) + +#define nr64_pcs(reg) readq(np->regs + np->pcs_off + (reg)) +#define nw64_pcs(reg, val) writeq((val), np->regs + np->pcs_off + (reg)) + +#define nr64_xpcs(reg) readq(np->regs + np->xpcs_off + (reg)) +#define nw64_xpcs(reg, val) writeq((val), np->regs + np->xpcs_off + (reg)) + +#define NIU_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) + +static int niu_debug; +static int debug = -1; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "NIU debug level"); + +#define niudbg(TYPE, f, a...) \ +do { if ((np)->msg_enable & NETIF_MSG_##TYPE) \ + printk(KERN_DEBUG PFX f, ## a); \ +} while (0) + +#define niuinfo(TYPE, f, a...) \ +do { if ((np)->msg_enable & NETIF_MSG_##TYPE) \ + printk(KERN_INFO PFX f, ## a); \ +} while (0) + +#define niuwarn(TYPE, f, a...) \ +do { if ((np)->msg_enable & NETIF_MSG_##TYPE) \ + printk(KERN_WARNING PFX f, ## a); \ +} while (0) + +#define niu_lock_parent(np, flags) \ + spin_lock_irqsave(&np->parent->lock, flags) +#define niu_unlock_parent(np, flags) \ + spin_unlock_irqrestore(&np->parent->lock, flags) + +static int __niu_wait_bits_clear_mac(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay) +{ + while (--limit >= 0) { + u64 val = nr64_mac(reg); + + if (!(val & bits)) + break; + udelay(delay); + } + if (limit < 0) + return -ENODEV; + return 0; +} + +static int __niu_set_and_wait_clear_mac(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay, + const char *reg_name) +{ + int err; + + nw64_mac(reg, bits); + err = __niu_wait_bits_clear_mac(np, reg, bits, limit, delay); + if (err) + dev_err(np->device, PFX "%s: bits (%llx) of register %s " + "would not clear, val[%llx]\n", + np->dev->name, (unsigned long long) bits, reg_name, + (unsigned long long) nr64_mac(reg)); + return err; +} + +#define niu_set_and_wait_clear_mac(NP, REG, BITS, LIMIT, DELAY, REG_NAME) \ +({ BUILD_BUG_ON(LIMIT <= 0 || DELAY < 0); \ + __niu_set_and_wait_clear_mac(NP, REG, BITS, LIMIT, DELAY, REG_NAME); \ +}) + +static int __niu_wait_bits_clear_ipp(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay) +{ + while (--limit >= 0) { + u64 val = nr64_ipp(reg); + + if (!(val & bits)) + break; + udelay(delay); + } + if (limit < 0) + return -ENODEV; + return 0; +} + +static int __niu_set_and_wait_clear_ipp(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay, + const char *reg_name) +{ + int err; + u64 val; + + val = nr64_ipp(reg); + val |= bits; + nw64_ipp(reg, val); + + err = __niu_wait_bits_clear_ipp(np, reg, bits, limit, delay); + if (err) + dev_err(np->device, PFX "%s: bits (%llx) of register %s " + "would not clear, val[%llx]\n", + np->dev->name, (unsigned long long) bits, reg_name, + (unsigned long long) nr64_ipp(reg)); + return err; +} + +#define niu_set_and_wait_clear_ipp(NP, REG, BITS, LIMIT, DELAY, REG_NAME) \ +({ BUILD_BUG_ON(LIMIT <= 0 || DELAY < 0); \ + __niu_set_and_wait_clear_ipp(NP, REG, BITS, LIMIT, DELAY, REG_NAME); \ +}) + +static int __niu_wait_bits_clear(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay) +{ + while (--limit >= 0) { + u64 val = nr64(reg); + + if (!(val & bits)) + break; + udelay(delay); + } + if (limit < 0) + return -ENODEV; + return 0; +} + +#define niu_wait_bits_clear(NP, REG, BITS, LIMIT, DELAY) \ +({ BUILD_BUG_ON(LIMIT <= 0 || DELAY < 0); \ + __niu_wait_bits_clear(NP, REG, BITS, LIMIT, DELAY); \ +}) + +static int __niu_set_and_wait_clear(struct niu *np, unsigned long reg, + u64 bits, int limit, int delay, + const char *reg_name) +{ + int err; + + nw64(reg, bits); + err = __niu_wait_bits_clear(np, reg, bits, limit, delay); + if (err) + dev_err(np->device, PFX "%s: bits (%llx) of register %s " + "would not clear, val[%llx]\n", + np->dev->name, (unsigned long long) bits, reg_name, + (unsigned long long) nr64(reg)); + return err; +} + +#define niu_set_and_wait_clear(NP, REG, BITS, LIMIT, DELAY, REG_NAME) \ +({ BUILD_BUG_ON(LIMIT <= 0 || DELAY < 0); \ + __niu_set_and_wait_clear(NP, REG, BITS, LIMIT, DELAY, REG_NAME); \ +}) + +static void niu_ldg_rearm(struct niu *np, struct niu_ldg *lp, int on) +{ + u64 val = (u64) lp->timer; + + if (on) + val |= LDG_IMGMT_ARM; + + nw64(LDG_IMGMT(lp->ldg_num), val); +} + +static int niu_ldn_irq_enable(struct niu *np, int ldn, int on) +{ + unsigned long mask_reg, bits; + u64 val; + + if (ldn < 0 || ldn > LDN_MAX) + return -EINVAL; + + if (ldn < 64) { + mask_reg = LD_IM0(ldn); + bits = LD_IM0_MASK; + } else { + mask_reg = LD_IM1(ldn - 64); + bits = LD_IM1_MASK; + } + + val = nr64(mask_reg); + if (on) + val &= ~bits; + else + val |= bits; + nw64(mask_reg, val); + + return 0; +} + +static int niu_enable_ldn_in_ldg(struct niu *np, struct niu_ldg *lp, int on) +{ + struct niu_parent *parent = np->parent; + int i; + + for (i = 0; i <= LDN_MAX; i++) { + int err; + + if (parent->ldg_map[i] != lp->ldg_num) + continue; + + err = niu_ldn_irq_enable(np, i, on); + if (err) + return err; + } + return 0; +} + +static int niu_enable_interrupts(struct niu *np, int on) +{ + int i; + + for (i = 0; i < np->num_ldg; i++) { + struct niu_ldg *lp = &np->ldg[i]; + int err; + + err = niu_enable_ldn_in_ldg(np, lp, on); + if (err) + return err; + } + for (i = 0; i < np->num_ldg; i++) + niu_ldg_rearm(np, &np->ldg[i], on); + + return 0; +} + +static u32 phy_encode(u32 type, int port) +{ + return (type << (port * 2)); +} + +static u32 phy_decode(u32 val, int port) +{ + return (val >> (port * 2)) & PORT_TYPE_MASK; +} + +static int mdio_wait(struct niu *np) +{ + int limit = 1000; + u64 val; + + while (--limit > 0) { + val = nr64(MIF_FRAME_OUTPUT); + if ((val >> MIF_FRAME_OUTPUT_TA_SHIFT) & 0x1) + return val & MIF_FRAME_OUTPUT_DATA; + + udelay(10); + } + + return -ENODEV; +} + +static int mdio_read(struct niu *np, int port, int dev, int reg) +{ + int err; + + nw64(MIF_FRAME_OUTPUT, MDIO_ADDR_OP(port, dev, reg)); + err = mdio_wait(np); + if (err < 0) + return err; + + nw64(MIF_FRAME_OUTPUT, MDIO_READ_OP(port, dev)); + return mdio_wait(np); +} + +static int mdio_write(struct niu *np, int port, int dev, int reg, int data) +{ + int err; + + nw64(MIF_FRAME_OUTPUT, MDIO_ADDR_OP(port, dev, reg)); + err = mdio_wait(np); + if (err < 0) + return err; + + nw64(MIF_FRAME_OUTPUT, MDIO_WRITE_OP(port, dev, data)); + err = mdio_wait(np); + if (err < 0) + return err; + + return 0; +} + +static int mii_read(struct niu *np, int port, int reg) +{ + nw64(MIF_FRAME_OUTPUT, MII_READ_OP(port, reg)); + return mdio_wait(np); +} + +static int mii_write(struct niu *np, int port, int reg, int data) +{ + int err; + + nw64(MIF_FRAME_OUTPUT, MII_WRITE_OP(port, reg, data)); + err = mdio_wait(np); + if (err < 0) + return err; + + return 0; +} + +static int esr2_set_tx_cfg(struct niu *np, unsigned long channel, u32 val) +{ + int err; + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_TX_CFG_L(channel), + val & 0xffff); + if (!err) + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_TX_CFG_H(channel), + val >> 16); + return err; +} + +static int esr2_set_rx_cfg(struct niu *np, unsigned long channel, u32 val) +{ + int err; + + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_RX_CFG_L(channel), + val & 0xffff); + if (!err) + err = mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_RX_CFG_H(channel), + val >> 16); + return err; +} + +/* Mode is always 10G fiber. */ +static int serdes_init_niu(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u32 tx_cfg, rx_cfg; + unsigned long i; + + tx_cfg = (PLL_TX_CFG_ENTX | PLL_TX_CFG_SWING_1375MV); + rx_cfg = (PLL_RX_CFG_ENRX | PLL_RX_CFG_TERM_0P8VDDT | + PLL_RX_CFG_ALIGN_ENA | PLL_RX_CFG_LOS_LTHRESH | + PLL_RX_CFG_EQ_LP_ADAPTIVE); + + if (lp->loopback_mode == LOOPBACK_PHY) { + u16 test_cfg = PLL_TEST_CFG_LOOPBACK_CML_DIS; + + mdio_write(np, np->port, NIU_ESR2_DEV_ADDR, + ESR2_TI_PLL_TEST_CFG_L, test_cfg); + + tx_cfg |= PLL_TX_CFG_ENTEST; + rx_cfg |= PLL_RX_CFG_ENTEST; + } + + /* Initialize all 4 lanes of the SERDES. */ + for (i = 0; i < 4; i++) { + int err = esr2_set_tx_cfg(np, i, tx_cfg); + if (err) + return err; + } + + for (i = 0; i < 4; i++) { + int err = esr2_set_rx_cfg(np, i, rx_cfg); + if (err) + return err; + } + + return 0; +} + +static int esr_read_rxtx_ctrl(struct niu *np, unsigned long chan, u32 *val) +{ + int err; + + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, ESR_RXTX_CTRL_L(chan)); + if (err >= 0) { + *val = (err & 0xffff); + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_CTRL_H(chan)); + if (err >= 0) + *val |= ((err & 0xffff) << 16); + err = 0; + } + return err; +} + +static int esr_read_glue0(struct niu *np, unsigned long chan, u32 *val) +{ + int err; + + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, + ESR_GLUE_CTRL0_L(chan)); + if (err >= 0) { + *val = (err & 0xffff); + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, + ESR_GLUE_CTRL0_H(chan)); + if (err >= 0) { + *val |= ((err & 0xffff) << 16); + err = 0; + } + } + return err; +} + +static int esr_read_reset(struct niu *np, u32 *val) +{ + int err; + + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_L); + if (err >= 0) { + *val = (err & 0xffff); + err = mdio_read(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_H); + if (err >= 0) { + *val |= ((err & 0xffff) << 16); + err = 0; + } + } + return err; +} + +static int esr_write_rxtx_ctrl(struct niu *np, unsigned long chan, u32 val) +{ + int err; + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_CTRL_L(chan), val & 0xffff); + if (!err) + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_CTRL_H(chan), (val >> 16)); + return err; +} + +static int esr_write_glue0(struct niu *np, unsigned long chan, u32 val) +{ + int err; + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_GLUE_CTRL0_L(chan), val & 0xffff); + if (!err) + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_GLUE_CTRL0_H(chan), (val >> 16)); + return err; +} + +static int esr_reset(struct niu *np) +{ + u32 reset; + int err; + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_L, 0x0000); + if (err) + return err; + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_H, 0xffff); + if (err) + return err; + udelay(200); + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_L, 0xffff); + if (err) + return err; + udelay(200); + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, + ESR_RXTX_RESET_CTRL_H, 0x0000); + if (err) + return err; + udelay(200); + + err = esr_read_reset(np, &reset); + if (err) + return err; + if (reset != 0) { + dev_err(np->device, PFX "Port %u ESR_RESET " + "did not clear [%08x]\n", + np->port, reset); + return -ENODEV; + } + + return 0; +} + +static int serdes_init_10g(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + unsigned long ctrl_reg, test_cfg_reg, i; + u64 ctrl_val, test_cfg_val, sig, mask, val; + int err; + + switch (np->port) { + case 0: + ctrl_reg = ENET_SERDES_0_CTRL_CFG; + test_cfg_reg = ENET_SERDES_0_TEST_CFG; + break; + case 1: + ctrl_reg = ENET_SERDES_1_CTRL_CFG; + test_cfg_reg = ENET_SERDES_1_TEST_CFG; + break; + + default: + return -EINVAL; + } + ctrl_val = (ENET_SERDES_CTRL_SDET_0 | + ENET_SERDES_CTRL_SDET_1 | + ENET_SERDES_CTRL_SDET_2 | + ENET_SERDES_CTRL_SDET_3 | + (0x5 << ENET_SERDES_CTRL_EMPH_0_SHIFT) | + (0x5 << ENET_SERDES_CTRL_EMPH_1_SHIFT) | + (0x5 << ENET_SERDES_CTRL_EMPH_2_SHIFT) | + (0x5 << ENET_SERDES_CTRL_EMPH_3_SHIFT) | + (0x1 << ENET_SERDES_CTRL_LADJ_0_SHIFT) | + (0x1 << ENET_SERDES_CTRL_LADJ_1_SHIFT) | + (0x1 << ENET_SERDES_CTRL_LADJ_2_SHIFT) | + (0x1 << ENET_SERDES_CTRL_LADJ_3_SHIFT)); + test_cfg_val = 0; + + if (lp->loopback_mode == LOOPBACK_PHY) { + test_cfg_val |= ((ENET_TEST_MD_PAD_LOOPBACK << + ENET_SERDES_TEST_MD_0_SHIFT) | + (ENET_TEST_MD_PAD_LOOPBACK << + ENET_SERDES_TEST_MD_1_SHIFT) | + (ENET_TEST_MD_PAD_LOOPBACK << + ENET_SERDES_TEST_MD_2_SHIFT) | + (ENET_TEST_MD_PAD_LOOPBACK << + ENET_SERDES_TEST_MD_3_SHIFT)); + } + + nw64(ctrl_reg, ctrl_val); + nw64(test_cfg_reg, test_cfg_val); + + /* Initialize all 4 lanes of the SERDES. */ + for (i = 0; i < 4; i++) { + u32 rxtx_ctrl, glue0; + + err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl); + if (err) + return err; + err = esr_read_glue0(np, i, &glue0); + if (err) + return err; + + rxtx_ctrl &= ~(ESR_RXTX_CTRL_VMUXLO); + rxtx_ctrl |= (ESR_RXTX_CTRL_ENSTRETCH | + (2 << ESR_RXTX_CTRL_VMUXLO_SHIFT)); + + glue0 &= ~(ESR_GLUE_CTRL0_SRATE | + ESR_GLUE_CTRL0_THCNT | + ESR_GLUE_CTRL0_BLTIME); + glue0 |= (ESR_GLUE_CTRL0_RXLOSENAB | + (0xf << ESR_GLUE_CTRL0_SRATE_SHIFT) | + (0xff << ESR_GLUE_CTRL0_THCNT_SHIFT) | + (BLTIME_300_CYCLES << + ESR_GLUE_CTRL0_BLTIME_SHIFT)); + + err = esr_write_rxtx_ctrl(np, i, rxtx_ctrl); + if (err) + return err; + err = esr_write_glue0(np, i, glue0); + if (err) + return err; + } + + err = esr_reset(np); + if (err) + return err; + + sig = nr64(ESR_INT_SIGNALS); + switch (np->port) { + case 0: + mask = ESR_INT_SIGNALS_P0_BITS; + val = (ESR_INT_SRDY0_P0 | + ESR_INT_DET0_P0 | + ESR_INT_XSRDY_P0 | + ESR_INT_XDP_P0_CH3 | + ESR_INT_XDP_P0_CH2 | + ESR_INT_XDP_P0_CH1 | + ESR_INT_XDP_P0_CH0); + break; + + case 1: + mask = ESR_INT_SIGNALS_P1_BITS; + val = (ESR_INT_SRDY0_P1 | + ESR_INT_DET0_P1 | + ESR_INT_XSRDY_P1 | + ESR_INT_XDP_P1_CH3 | + ESR_INT_XDP_P1_CH2 | + ESR_INT_XDP_P1_CH1 | + ESR_INT_XDP_P1_CH0); + break; + + default: + return -EINVAL; + } + + if ((sig & mask) != val) { + dev_err(np->device, PFX "Port %u signal bits [%08x] are not " + "[%08x]\n", np->port, (int) (sig & mask), (int) val); + return -ENODEV; + } + + return 0; +} + +static int serdes_init_1g(struct niu *np) +{ + u64 val; + + val = nr64(ENET_SERDES_1_PLL_CFG); + val &= ~ENET_SERDES_PLL_FBDIV2; + switch (np->port) { + case 0: + val |= ENET_SERDES_PLL_HRATE0; + break; + case 1: + val |= ENET_SERDES_PLL_HRATE1; + break; + case 2: + val |= ENET_SERDES_PLL_HRATE2; + break; + case 3: + val |= ENET_SERDES_PLL_HRATE3; + break; + default: + return -EINVAL; + } + nw64(ENET_SERDES_1_PLL_CFG, val); + + return 0; +} + +static int bcm8704_reset(struct niu *np) +{ + int err, limit; + + err = mdio_read(np, np->phy_addr, + BCM8704_PHYXS_DEV_ADDR, MII_BMCR); + if (err < 0) + return err; + err |= BMCR_RESET; + err = mdio_write(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR, + MII_BMCR, err); + if (err) + return err; + + limit = 1000; + while (--limit >= 0) { + err = mdio_read(np, np->phy_addr, + BCM8704_PHYXS_DEV_ADDR, MII_BMCR); + if (err < 0) + return err; + if (!(err & BMCR_RESET)) + break; + } + if (limit < 0) { + dev_err(np->device, PFX "Port %u PHY will not reset " + "(bmcr=%04x)\n", np->port, (err & 0xffff)); + return -ENODEV; + } + return 0; +} + +/* When written, certain PHY registers need to be read back twice + * in order for the bits to settle properly. + */ +static int bcm8704_user_dev3_readback(struct niu *np, int reg) +{ + int err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, reg); + if (err < 0) + return err; + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, reg); + if (err < 0) + return err; + return 0; +} + +static int bcm8704_init_user_dev3(struct niu *np) +{ + int err; + + err = mdio_write(np, np->phy_addr, + BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL, + (USER_CONTROL_OPTXRST_LVL | + USER_CONTROL_OPBIASFLT_LVL | + USER_CONTROL_OBTMPFLT_LVL | + USER_CONTROL_OPPRFLT_LVL | + USER_CONTROL_OPTXFLT_LVL | + USER_CONTROL_OPRXLOS_LVL | + USER_CONTROL_OPRXFLT_LVL | + USER_CONTROL_OPTXON_LVL | + (0x3f << USER_CONTROL_RES1_SHIFT))); + if (err) + return err; + + err = mdio_write(np, np->phy_addr, + BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL, + (USER_PMD_TX_CTL_XFP_CLKEN | + (1 << USER_PMD_TX_CTL_TX_DAC_TXD_SH) | + (2 << USER_PMD_TX_CTL_TX_DAC_TXCK_SH) | + USER_PMD_TX_CTL_TSCK_LPWREN)); + if (err) + return err; + + err = bcm8704_user_dev3_readback(np, BCM8704_USER_CONTROL); + if (err) + return err; + err = bcm8704_user_dev3_readback(np, BCM8704_USER_PMD_TX_CONTROL); + if (err) + return err; + + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_OPT_DIGITAL_CTRL); + if (err < 0) + return err; + err &= ~USER_ODIG_CTRL_GPIOS; + err |= (0x3 << USER_ODIG_CTRL_GPIOS_SHIFT); + err = mdio_write(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_OPT_DIGITAL_CTRL, err); + if (err) + return err; + + mdelay(1000); + + return 0; +} + +static int xcvr_init_10g(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u16 analog_stat0, tx_alarm_status; + int err; + u64 val; + + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_LED_POLARITY; + val |= XMAC_CONFIG_FORCE_LED_ON; + nw64_mac(XMAC_CONFIG, val); + + /* XXX shared resource, lock parent XXX */ + val = nr64(MIF_CONFIG); + val |= MIF_CONFIG_INDIRECT_MODE; + nw64(MIF_CONFIG, val); + + err = bcm8704_reset(np); + if (err) + return err; + + err = bcm8704_init_user_dev3(np); + if (err) + return err; + + err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + MII_BMCR); + if (err < 0) + return err; + err &= ~BMCR_LOOPBACK; + + if (lp->loopback_mode == LOOPBACK_MAC) + err |= BMCR_LOOPBACK; + + err = mdio_write(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + MII_BMCR, err); + if (err) + return err; + +#if 1 + err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, + MII_STAT1000); + if (err < 0) + return err; + pr_info(PFX "Port %u PMA_PMD(MII_STAT1000) [%04x]\n", + np->port, err); + + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, 0x20); + if (err < 0) + return err; + pr_info(PFX "Port %u USER_DEV3(0x20) [%04x]\n", + np->port, err); + + err = mdio_read(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR, + MII_NWAYTEST); + if (err < 0) + return err; + pr_info(PFX "Port %u PHYXS(MII_NWAYTEST) [%04x]\n", + np->port, err); +#endif + + /* XXX dig this out it might not be so useful XXX */ + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_ANALOG_STATUS0); + if (err < 0) + return err; + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_ANALOG_STATUS0); + if (err < 0) + return err; + analog_stat0 = err; + + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_TX_ALARM_STATUS); + if (err < 0) + return err; + err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, + BCM8704_USER_TX_ALARM_STATUS); + if (err < 0) + return err; + tx_alarm_status = err; + + if (analog_stat0 != 0x03fc) { + if ((analog_stat0 == 0x43bc) && (tx_alarm_status != 0)) { + pr_info(PFX "Port %u cable not connected " + "or bad cable.\n", np->port); + } else if (analog_stat0 == 0x639c) { + pr_info(PFX "Port %u optical module is bad " + "or missing.\n", np->port); + } + } + + return 0; +} + +static int mii_reset(struct niu *np) +{ + int limit, err; + + err = mii_write(np, np->phy_addr, MII_BMCR, BMCR_RESET); + if (err) + return err; + + limit = 1000; + while (--limit >= 0) { + udelay(500); + err = mii_read(np, np->phy_addr, MII_BMCR); + if (err < 0) + return err; + if (!(err & BMCR_RESET)) + break; + } + if (limit < 0) { + dev_err(np->device, PFX "Port %u MII would not reset, " + "bmcr[%04x]\n", np->port, err); + return -ENODEV; + } + + return 0; +} + +static int mii_init_common(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u16 bmcr, bmsr, adv, estat; + int err; + + err = mii_reset(np); + if (err) + return err; + + err = mii_read(np, np->phy_addr, MII_BMSR); + if (err < 0) + return err; + bmsr = err; + + estat = 0; + if (bmsr & BMSR_ESTATEN) { + err = mii_read(np, np->phy_addr, MII_ESTATUS); + if (err < 0) + return err; + estat = err; + } + + bmcr = 0; + err = mii_write(np, np->phy_addr, MII_BMCR, bmcr); + if (err) + return err; + + if (lp->loopback_mode == LOOPBACK_MAC) { + bmcr |= BMCR_LOOPBACK; + if (lp->active_speed == SPEED_1000) + bmcr |= BMCR_SPEED1000; + if (lp->active_duplex == DUPLEX_FULL) + bmcr |= BMCR_FULLDPLX; + } + + if (lp->loopback_mode == LOOPBACK_PHY) { + u16 aux; + + aux = (BCM5464R_AUX_CTL_EXT_LB | + BCM5464R_AUX_CTL_WRITE_1); + err = mii_write(np, np->phy_addr, BCM5464R_AUX_CTL, aux); + if (err) + return err; + } + + /* XXX configurable XXX */ + /* XXX for now don't advertise half-duplex or asym pause... XXX */ + adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP; + if (bmsr & BMSR_10FULL) + adv |= ADVERTISE_10FULL; + if (bmsr & BMSR_100FULL) + adv |= ADVERTISE_100FULL; + err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv); + if (err) + return err; + + if (bmsr & BMSR_ESTATEN) { + u16 ctrl1000 = 0; + + if (estat & ESTATUS_1000_TFULL) + ctrl1000 |= ADVERTISE_1000FULL; + err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000); + if (err) + return err; + } + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); + + err = mii_write(np, np->phy_addr, MII_BMCR, bmcr); + if (err) + return err; + + err = mii_read(np, np->phy_addr, MII_BMCR); + if (err < 0) + return err; + err = mii_read(np, np->phy_addr, MII_BMSR); + if (err < 0) + return err; +#if 0 + pr_info(PFX "Port %u after MII init bmcr[%04x] bmsr[%04x]\n", + np->port, bmcr, bmsr); +#endif + + return 0; +} + +static int xcvr_init_1g(struct niu *np) +{ + u64 val; + + /* XXX shared resource, lock parent XXX */ + val = nr64(MIF_CONFIG); + val &= ~MIF_CONFIG_INDIRECT_MODE; + nw64(MIF_CONFIG, val); + + return mii_init_common(np); +} + +static int niu_xcvr_init(struct niu *np) +{ + const struct niu_phy_ops *ops = np->phy_ops; + int err; + + err = 0; + if (ops->xcvr_init) + err = ops->xcvr_init(np); + + return err; +} + +static int niu_serdes_init(struct niu *np) +{ + const struct niu_phy_ops *ops = np->phy_ops; + int err; + + err = 0; + if (ops->serdes_init) + err = ops->serdes_init(np); + + return err; +} + +static void niu_init_xif(struct niu *); +static void niu_handle_led(struct niu *, int status); + +static int niu_link_status_common(struct niu *np, int link_up) +{ + struct niu_link_config *lp = &np->link_config; + struct net_device *dev = np->dev; + unsigned long flags; + + if (!netif_carrier_ok(dev) && link_up) { + niuinfo(LINK, "%s: Link is up at %s, %s duplex\n", + dev->name, + (lp->active_speed == SPEED_10000 ? + "10Gb/sec" : + (lp->active_speed == SPEED_1000 ? + "1Gb/sec" : + (lp->active_speed == SPEED_100 ? + "100Mbit/sec" : "10Mbit/sec"))), + (lp->active_duplex == DUPLEX_FULL ? + "full" : "half")); + + spin_lock_irqsave(&np->lock, flags); + niu_init_xif(np); + niu_handle_led(np, 1); + spin_unlock_irqrestore(&np->lock, flags); + + netif_carrier_on(dev); + } else if (netif_carrier_ok(dev) && !link_up) { + niuwarn(LINK, "%s: Link is down\n", dev->name); + spin_lock_irqsave(&np->lock, flags); + niu_handle_led(np, 0); + spin_unlock_irqrestore(&np->lock, flags); + netif_carrier_off(dev); + } + + return 0; +} + +static int link_status_10g(struct niu *np, int *link_up_p) +{ + unsigned long flags; + int err, link_up; + + link_up = 0; + + spin_lock_irqsave(&np->lock, flags); + + err = -EINVAL; + if (np->link_config.loopback_mode != LOOPBACK_DISABLED) + goto out; + + err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, + BCM8704_PMD_RCV_SIGDET); + if (err < 0) + goto out; + if (!(err & PMD_RCV_SIGDET_GLOBAL)) { + err = 0; + goto out; + } + + err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, + BCM8704_PCS_10G_R_STATUS); + if (err < 0) + goto out; + if (!(err & PCS_10G_R_STATUS_BLK_LOCK)) { + err = 0; + goto out; + } + + err = mdio_read(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR, + BCM8704_PHYXS_XGXS_LANE_STAT); + if (err < 0) + goto out; + + if (err != (PHYXS_XGXS_LANE_STAT_ALINGED | + PHYXS_XGXS_LANE_STAT_MAGIC | + PHYXS_XGXS_LANE_STAT_LANE3 | + PHYXS_XGXS_LANE_STAT_LANE2 | + PHYXS_XGXS_LANE_STAT_LANE1 | + PHYXS_XGXS_LANE_STAT_LANE0)) { + err = 0; + goto out; + } + + link_up = 1; + np->link_config.active_speed = SPEED_10000; + np->link_config.active_duplex = DUPLEX_FULL; + err = 0; + +out: + spin_unlock_irqrestore(&np->lock, flags); + + *link_up_p = link_up; + return err; +} + +static int link_status_1g(struct niu *np, int *link_up_p) +{ + u16 current_speed, bmsr; + unsigned long flags; + u8 current_duplex; + int err, link_up; + + link_up = 0; + current_speed = SPEED_INVALID; + current_duplex = DUPLEX_INVALID; + + spin_lock_irqsave(&np->lock, flags); + + err = -EINVAL; + if (np->link_config.loopback_mode != LOOPBACK_DISABLED) + goto out; + + err = mii_read(np, np->phy_addr, MII_BMSR); + if (err < 0) + goto out; + + bmsr = err; + if (bmsr & BMSR_LSTATUS) { + u16 adv, lpa, common, estat; + + err = mii_read(np, np->phy_addr, MII_ADVERTISE); + if (err < 0) + goto out; + adv = err; + + err = mii_read(np, np->phy_addr, MII_LPA); + if (err < 0) + goto out; + lpa = err; + + common = adv & lpa; + + err = mii_read(np, np->phy_addr, MII_ESTATUS); + if (err < 0) + goto out; + estat = err; + + link_up = 1; + if (estat & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) { + current_speed = SPEED_1000; + if (estat & ESTATUS_1000_TFULL) + current_duplex = DUPLEX_FULL; + else + current_duplex = DUPLEX_HALF; + } else { + if (common & ADVERTISE_100BASE4) { + current_speed = SPEED_100; + current_duplex = DUPLEX_HALF; + } else if (common & ADVERTISE_100FULL) { + current_speed = SPEED_100; + current_duplex = DUPLEX_FULL; + } else if (common & ADVERTISE_100HALF) { + current_speed = SPEED_100; + current_duplex = DUPLEX_HALF; + } else if (common & ADVERTISE_10FULL) { + current_speed = SPEED_10; + current_duplex = DUPLEX_FULL; + } else if (common & ADVERTISE_10HALF) { + current_speed = SPEED_10; + current_duplex = DUPLEX_HALF; + } else + link_up = 0; + } + } + err = 0; + +out: + spin_unlock_irqrestore(&np->lock, flags); + + *link_up_p = link_up; + return err; +} + +static int niu_link_status(struct niu *np, int *link_up_p) +{ + const struct niu_phy_ops *ops = np->phy_ops; + int err; + + err = 0; + if (ops->link_status) + err = ops->link_status(np, link_up_p); + + return err; +} + +static void niu_timer(unsigned long __opaque) +{ + struct niu *np = (struct niu *) __opaque; + unsigned long off; + int err, link_up; + + err = niu_link_status(np, &link_up); + if (!err) + niu_link_status_common(np, link_up); + + if (netif_carrier_ok(np->dev)) + off = 5 * HZ; + else + off = 1 * HZ; + np->timer.expires = jiffies + off; + + add_timer(&np->timer); +} + +static const struct niu_phy_ops phy_ops_10g_fiber_niu = { + .serdes_init = serdes_init_niu, + .xcvr_init = xcvr_init_10g, + .link_status = link_status_10g, +}; + +static const struct niu_phy_ops phy_ops_10g_fiber = { + .serdes_init = serdes_init_10g, + .xcvr_init = xcvr_init_10g, + .link_status = link_status_10g, +}; + +static const struct niu_phy_ops phy_ops_10g_copper = { + .serdes_init = serdes_init_10g, + .link_status = link_status_10g, /* XXX */ +}; + +static const struct niu_phy_ops phy_ops_1g_fiber = { + .serdes_init = serdes_init_1g, + .xcvr_init = xcvr_init_1g, + .link_status = link_status_1g, +}; + +static const struct niu_phy_ops phy_ops_1g_copper = { + .xcvr_init = xcvr_init_1g, + .link_status = link_status_1g, +}; + +struct niu_phy_template { + const struct niu_phy_ops *ops; + u32 phy_addr_base; +}; + +static const struct niu_phy_template phy_template_niu = { + .ops = &phy_ops_10g_fiber_niu, + .phy_addr_base = 16, +}; + +static const struct niu_phy_template phy_template_10g_fiber = { + .ops = &phy_ops_10g_fiber, + .phy_addr_base = 8, +}; + +static const struct niu_phy_template phy_template_10g_copper = { + .ops = &phy_ops_10g_copper, + .phy_addr_base = 10, +}; + +static const struct niu_phy_template phy_template_1g_fiber = { + .ops = &phy_ops_1g_fiber, + .phy_addr_base = 0, +}; + +static const struct niu_phy_template phy_template_1g_copper = { + .ops = &phy_ops_1g_copper, + .phy_addr_base = 0, +}; + +static int niu_determine_phy_disposition(struct niu *np) +{ + struct niu_parent *parent = np->parent; + u8 plat_type = parent->plat_type; + const struct niu_phy_template *tp; + u32 phy_addr_off = 0; + + if (plat_type == PLAT_TYPE_NIU) { + tp = &phy_template_niu; + phy_addr_off += np->port; + } else { + switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { + case 0: + /* 1G copper */ + tp = &phy_template_1g_copper; + if (plat_type == PLAT_TYPE_VF_P0) + phy_addr_off = 10; + else if (plat_type == PLAT_TYPE_VF_P1) + phy_addr_off = 26; + + phy_addr_off += (np->port ^ 0x3); + break; + + case NIU_FLAGS_10G: + /* 10G copper */ + tp = &phy_template_1g_copper; + break; + + case NIU_FLAGS_FIBER: + /* 1G fiber */ + tp = &phy_template_1g_fiber; + break; + + case NIU_FLAGS_10G | NIU_FLAGS_FIBER: + /* 10G fiber */ + tp = &phy_template_10g_fiber; + if (plat_type == PLAT_TYPE_VF_P0 || + plat_type == PLAT_TYPE_VF_P1) + phy_addr_off = 8; + phy_addr_off += np->port; + break; + + default: + return -EINVAL; + } + } + + np->phy_ops = tp->ops; + np->phy_addr = tp->phy_addr_base + phy_addr_off; + + return 0; +} + +static int niu_init_link(struct niu *np) +{ + struct niu_parent *parent = np->parent; + int err, ignore; + + if (parent->plat_type == PLAT_TYPE_NIU) { + err = niu_xcvr_init(np); + if (err) + return err; + msleep(200); + } + err = niu_serdes_init(np); + if (err) + return err; + msleep(200); + err = niu_xcvr_init(np); + if (!err) + niu_link_status(np, &ignore); + return 0; +} + +static void niu_set_primary_mac(struct niu *np, unsigned char *addr) +{ + u16 reg0 = addr[4] << 8 | addr[5]; + u16 reg1 = addr[2] << 8 | addr[3]; + u16 reg2 = addr[0] << 8 | addr[1]; + + if (np->flags & NIU_FLAGS_XMAC) { + nw64_mac(XMAC_ADDR0, reg0); + nw64_mac(XMAC_ADDR1, reg1); + nw64_mac(XMAC_ADDR2, reg2); + } else { + nw64_mac(BMAC_ADDR0, reg0); + nw64_mac(BMAC_ADDR1, reg1); + nw64_mac(BMAC_ADDR2, reg2); + } +} + +static int niu_num_alt_addr(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + return XMAC_NUM_ALT_ADDR; + else + return BMAC_NUM_ALT_ADDR; +} + +#if 0 +static int niu_set_alt_mac(struct niu *np, int index, unsigned char *addr) +{ + u16 reg0 = addr[4] << 8 | addr[5]; + u16 reg1 = addr[2] << 8 | addr[3]; + u16 reg2 = addr[0] << 8 | addr[1]; + + if (index >= niu_num_alt_addr(np)) + return -EINVAL; + + if (np->flags & NIU_FLAGS_XMAC) { + nw64_mac(XMAC_ALT_ADDR0(index), reg0); + nw64_mac(XMAC_ALT_ADDR1(index), reg1); + nw64_mac(XMAC_ALT_ADDR2(index), reg2); + } else { + nw64_mac(BMAC_ALT_ADDR0(index), reg0); + nw64_mac(BMAC_ALT_ADDR1(index), reg1); + nw64_mac(BMAC_ALT_ADDR2(index), reg2); + } + + return 0; +} +#endif + +static int niu_enable_alt_mac(struct niu *np, int index, int on) +{ + unsigned long reg; + u64 val, mask; + + if (index >= niu_num_alt_addr(np)) + return -EINVAL; + + if (np->flags & NIU_FLAGS_XMAC) + reg = XMAC_ADDR_CMPEN; + else + reg = BMAC_ADDR_CMPEN; + + mask = 1 << index; + + val = nr64_mac(reg); + if (on) + val |= mask; + else + val &= ~mask; + nw64_mac(reg, val); + + return 0; +} + +static void __set_rdc_table_num_hw(struct niu *np, unsigned long reg, + int num, int mac_pref) +{ + u64 val = nr64_mac(reg); + val &= ~(HOST_INFO_MACRDCTBLN | HOST_INFO_MPR); + val |= num; + if (mac_pref) + val |= HOST_INFO_MPR; + nw64_mac(reg, val); +} + +static int __set_rdc_table_num(struct niu *np, + int xmac_index, int bmac_index, + int rdc_table_num, int mac_pref) +{ + unsigned long reg; + + if (rdc_table_num & ~HOST_INFO_MACRDCTBLN) + return -EINVAL; + if (np->flags & NIU_FLAGS_XMAC) + reg = XMAC_HOST_INFO(xmac_index); + else + reg = BMAC_HOST_INFO(bmac_index); + __set_rdc_table_num_hw(np, reg, rdc_table_num, mac_pref); + return 0; +} + +static int niu_set_primary_mac_rdc_table(struct niu *np, int table_num, + int mac_pref) +{ + return __set_rdc_table_num(np, 17, 0, table_num, mac_pref); +} + +static int niu_set_multicast_mac_rdc_table(struct niu *np, int table_num, + int mac_pref) +{ + return __set_rdc_table_num(np, 16, 8, table_num, mac_pref); +} + +static int niu_set_alt_mac_rdc_table(struct niu *np, int idx, + int table_num, int mac_pref) +{ + if (idx >= niu_num_alt_addr(np)) + return -EINVAL; + return __set_rdc_table_num(np, idx, idx + 1, table_num, mac_pref); +} + +static u64 vlan_entry_set_parity(u64 reg_val) +{ + u64 port01_mask; + u64 port23_mask; + + port01_mask = 0x00ff; + port23_mask = 0xff00; + + if (hweight64(reg_val & port01_mask) & 1) + reg_val |= ENET_VLAN_TBL_PARITY0; + else + reg_val &= ~ENET_VLAN_TBL_PARITY0; + + if (hweight64(reg_val & port23_mask) & 1) + reg_val |= ENET_VLAN_TBL_PARITY1; + else + reg_val &= ~ENET_VLAN_TBL_PARITY1; + + return reg_val; +} + +static void vlan_tbl_write(struct niu *np, unsigned long index, + int port, int vpr, int rdc_table) +{ + u64 reg_val = nr64(ENET_VLAN_TBL(index)); + + reg_val &= ~((ENET_VLAN_TBL_VPR | + ENET_VLAN_TBL_VLANRDCTBLN) << + ENET_VLAN_TBL_SHIFT(port)); + if (vpr) + reg_val |= (ENET_VLAN_TBL_VPR << + ENET_VLAN_TBL_SHIFT(port)); + reg_val |= (rdc_table << ENET_VLAN_TBL_SHIFT(port)); + + reg_val = vlan_entry_set_parity(reg_val); + + nw64(ENET_VLAN_TBL(index), reg_val); +} + +static void vlan_tbl_clear(struct niu *np) +{ + int i; + + for (i = 0; i < ENET_VLAN_TBL_NUM_ENTRIES; i++) + nw64(ENET_VLAN_TBL(i), 0); +} + +static int tcam_wait_bit(struct niu *np, u64 bit) +{ + int limit = 1000; + + while (--limit > 0) { + if (nr64(TCAM_CTL) & bit) + break; + udelay(1); + } + if (limit < 0) + return -ENODEV; + + return 0; +} + +static int tcam_flush(struct niu *np, int index) +{ + nw64(TCAM_KEY_0, 0x00); + nw64(TCAM_KEY_MASK_0, 0xff); + nw64(TCAM_CTL, (TCAM_CTL_RWC_TCAM_WRITE | index)); + + return tcam_wait_bit(np, TCAM_CTL_STAT); +} + +#if 0 +static int tcam_read(struct niu *np, int index, + u64 *key, u64 *mask) +{ + int err; + + nw64(TCAM_CTL, (TCAM_CTL_RWC_TCAM_READ | index)); + err = tcam_wait_bit(np, TCAM_CTL_STAT); + if (!err) { + key[0] = nr64(TCAM_KEY_0); + key[1] = nr64(TCAM_KEY_1); + key[2] = nr64(TCAM_KEY_2); + key[3] = nr64(TCAM_KEY_3); + mask[0] = nr64(TCAM_KEY_MASK_0); + mask[1] = nr64(TCAM_KEY_MASK_1); + mask[2] = nr64(TCAM_KEY_MASK_2); + mask[3] = nr64(TCAM_KEY_MASK_3); + } + return err; +} +#endif + +static int tcam_write(struct niu *np, int index, + u64 *key, u64 *mask) +{ + nw64(TCAM_KEY_0, key[0]); + nw64(TCAM_KEY_1, key[1]); + nw64(TCAM_KEY_2, key[2]); + nw64(TCAM_KEY_3, key[3]); + nw64(TCAM_KEY_MASK_0, mask[0]); + nw64(TCAM_KEY_MASK_1, mask[1]); + nw64(TCAM_KEY_MASK_2, mask[2]); + nw64(TCAM_KEY_MASK_3, mask[3]); + nw64(TCAM_CTL, (TCAM_CTL_RWC_TCAM_WRITE | index)); + + return tcam_wait_bit(np, TCAM_CTL_STAT); +} + +#if 0 +static int tcam_assoc_read(struct niu *np, int index, u64 *data) +{ + int err; + + nw64(TCAM_CTL, (TCAM_CTL_RWC_RAM_READ | index)); + err = tcam_wait_bit(np, TCAM_CTL_STAT); + if (!err) + *data = nr64(TCAM_KEY_1); + + return err; +} +#endif + +static int tcam_assoc_write(struct niu *np, int index, u64 assoc_data) +{ + nw64(TCAM_KEY_1, assoc_data); + nw64(TCAM_CTL, (TCAM_CTL_RWC_RAM_WRITE | index)); + + return tcam_wait_bit(np, TCAM_CTL_STAT); +} + +static void tcam_enable(struct niu *np, int on) +{ + u64 val = nr64(FFLP_CFG_1); + + if (on) + val &= ~FFLP_CFG_1_TCAM_DIS; + else + val |= FFLP_CFG_1_TCAM_DIS; + nw64(FFLP_CFG_1, val); +} + +static void tcam_set_lat_and_ratio(struct niu *np, u64 latency, u64 ratio) +{ + u64 val = nr64(FFLP_CFG_1); + + val &= ~(FFLP_CFG_1_FFLPINITDONE | + FFLP_CFG_1_CAMLAT | + FFLP_CFG_1_CAMRATIO); + val |= (latency << FFLP_CFG_1_CAMLAT_SHIFT); + val |= (ratio << FFLP_CFG_1_CAMRATIO_SHIFT); + nw64(FFLP_CFG_1, val); + + val = nr64(FFLP_CFG_1); + val |= FFLP_CFG_1_FFLPINITDONE; + nw64(FFLP_CFG_1, val); +} + +static int tcam_user_eth_class_enable(struct niu *np, unsigned long class, + int on) +{ + unsigned long reg; + u64 val; + + if (class < CLASS_CODE_ETHERTYPE1 || + class > CLASS_CODE_ETHERTYPE2) + return -EINVAL; + + reg = L2_CLS(class - CLASS_CODE_ETHERTYPE1); + val = nr64(reg); + if (on) + val |= L2_CLS_VLD; + else + val &= ~L2_CLS_VLD; + nw64(reg, val); + + return 0; +} + +#if 0 +static int tcam_user_eth_class_set(struct niu *np, unsigned long class, + u64 ether_type) +{ + unsigned long reg; + u64 val; + + if (class < CLASS_CODE_ETHERTYPE1 || + class > CLASS_CODE_ETHERTYPE2 || + (ether_type & ~(u64)0xffff) != 0) + return -EINVAL; + + reg = L2_CLS(class - CLASS_CODE_ETHERTYPE1); + val = nr64(reg); + val &= ~L2_CLS_ETYPE; + val |= (ether_type << L2_CLS_ETYPE_SHIFT); + nw64(reg, val); + + return 0; +} +#endif + +static int tcam_user_ip_class_enable(struct niu *np, unsigned long class, + int on) +{ + unsigned long reg; + u64 val; + + if (class < CLASS_CODE_USER_PROG1 || + class > CLASS_CODE_USER_PROG4) + return -EINVAL; + + reg = L3_CLS(class - CLASS_CODE_USER_PROG1); + val = nr64(reg); + if (on) + val |= L3_CLS_VALID; + else + val &= ~L3_CLS_VALID; + nw64(reg, val); + + return 0; +} + +#if 0 +static int tcam_user_ip_class_set(struct niu *np, unsigned long class, + int ipv6, u64 protocol_id, + u64 tos_mask, u64 tos_val) +{ + unsigned long reg; + u64 val; + + if (class < CLASS_CODE_USER_PROG1 || + class > CLASS_CODE_USER_PROG4 || + (protocol_id & ~(u64)0xff) != 0 || + (tos_mask & ~(u64)0xff) != 0 || + (tos_val & ~(u64)0xff) != 0) + return -EINVAL; + + reg = L3_CLS(class - CLASS_CODE_USER_PROG1); + val = nr64(reg); + val &= ~(L3_CLS_IPVER | L3_CLS_PID | + L3_CLS_TOSMASK | L3_CLS_TOS); + if (ipv6) + val |= L3_CLS_IPVER; + val |= (protocol_id << L3_CLS_PID_SHIFT); + val |= (tos_mask << L3_CLS_TOSMASK_SHIFT); + val |= (tos_val << L3_CLS_TOS_SHIFT); + nw64(reg, val); + + return 0; +} +#endif + +static int tcam_early_init(struct niu *np) +{ + unsigned long i; + int err; + + tcam_enable(np, 0); + tcam_set_lat_and_ratio(np, + DEFAULT_TCAM_LATENCY, + DEFAULT_TCAM_ACCESS_RATIO); + for (i = CLASS_CODE_ETHERTYPE1; i <= CLASS_CODE_ETHERTYPE2; i++) { + err = tcam_user_eth_class_enable(np, i, 0); + if (err) + return err; + } + for (i = CLASS_CODE_USER_PROG1; i <= CLASS_CODE_USER_PROG4; i++) { + err = tcam_user_ip_class_enable(np, i, 0); + if (err) + return err; + } + + return 0; +} + +static int tcam_flush_all(struct niu *np) +{ + unsigned long i; + + for (i = 0; i < np->parent->tcam_num_entries; i++) { + int err = tcam_flush(np, i); + if (err) + return err; + } + return 0; +} + +static u64 hash_addr_regval(unsigned long index, unsigned long num_entries) +{ + return ((u64)index | (num_entries == 1 ? + HASH_TBL_ADDR_AUTOINC : 0)); +} + +#if 0 +static int hash_read(struct niu *np, unsigned long partition, + unsigned long index, unsigned long num_entries, + u64 *data) +{ + u64 val = hash_addr_regval(index, num_entries); + unsigned long i; + + if (partition >= FCRAM_NUM_PARTITIONS || + index + num_entries > FCRAM_SIZE) + return -EINVAL; + + nw64(HASH_TBL_ADDR(partition), val); + for (i = 0; i < num_entries; i++) + data[i] = nr64(HASH_TBL_DATA(partition)); + + return 0; +} +#endif + +static int hash_write(struct niu *np, unsigned long partition, + unsigned long index, unsigned long num_entries, + u64 *data) +{ + u64 val = hash_addr_regval(index, num_entries); + unsigned long i; + + if (partition >= FCRAM_NUM_PARTITIONS || + index + (num_entries * 8) > FCRAM_SIZE) + return -EINVAL; + + nw64(HASH_TBL_ADDR(partition), val); + for (i = 0; i < num_entries; i++) + nw64(HASH_TBL_DATA(partition), data[i]); + + return 0; +} + +static void fflp_reset(struct niu *np) +{ + u64 val; + + nw64(FFLP_CFG_1, FFLP_CFG_1_PIO_FIO_RST); + udelay(10); + nw64(FFLP_CFG_1, 0); + + val = FFLP_CFG_1_FCRAMOUTDR_NORMAL | FFLP_CFG_1_FFLPINITDONE; + nw64(FFLP_CFG_1, val); +} + +static void fflp_set_timings(struct niu *np) +{ + u64 val = nr64(FFLP_CFG_1); + + val &= ~FFLP_CFG_1_FFLPINITDONE; + val |= (DEFAULT_FCRAMRATIO << FFLP_CFG_1_FCRAMRATIO_SHIFT); + nw64(FFLP_CFG_1, val); + + val = nr64(FFLP_CFG_1); + val |= FFLP_CFG_1_FFLPINITDONE; + nw64(FFLP_CFG_1, val); + + val = nr64(FCRAM_REF_TMR); + val &= ~(FCRAM_REF_TMR_MAX | FCRAM_REF_TMR_MIN); + val |= (DEFAULT_FCRAM_REFRESH_MAX << FCRAM_REF_TMR_MAX_SHIFT); + val |= (DEFAULT_FCRAM_REFRESH_MIN << FCRAM_REF_TMR_MIN_SHIFT); + nw64(FCRAM_REF_TMR, val); +} + +static int fflp_set_partition(struct niu *np, u64 partition, + u64 mask, u64 base, int enable) +{ + unsigned long reg; + u64 val; + + if (partition >= FCRAM_NUM_PARTITIONS || + (mask & ~(u64)0x1f) != 0 || + (base & ~(u64)0x1f) != 0) + return -EINVAL; + + reg = FLW_PRT_SEL(partition); + + val = nr64(reg); + val &= ~(FLW_PRT_SEL_EXT | FLW_PRT_SEL_MASK | FLW_PRT_SEL_BASE); + val |= (mask << FLW_PRT_SEL_MASK_SHIFT); + val |= (base << FLW_PRT_SEL_BASE_SHIFT); + if (enable) + val |= FLW_PRT_SEL_EXT; + nw64(reg, val); + + return 0; +} + +static int fflp_disable_all_partitions(struct niu *np) +{ + unsigned long i; + + for (i = 0; i < FCRAM_NUM_PARTITIONS; i++) { + int err = fflp_set_partition(np, 0, 0, 0, 0); + if (err) + return err; + } + return 0; +} + +static void fflp_llcsnap_enable(struct niu *np, int on) +{ + u64 val = nr64(FFLP_CFG_1); + + if (on) + val |= FFLP_CFG_1_LLCSNAP; + else + val &= ~FFLP_CFG_1_LLCSNAP; + nw64(FFLP_CFG_1, val); +} + +static void fflp_errors_enable(struct niu *np, int on) +{ + u64 val = nr64(FFLP_CFG_1); + + if (on) + val &= ~FFLP_CFG_1_ERRORDIS; + else + val |= FFLP_CFG_1_ERRORDIS; + nw64(FFLP_CFG_1, val); +} + +static int fflp_hash_clear(struct niu *np) +{ + struct fcram_hash_ipv4 ent; + unsigned long i; + + /* IPV4 hash entry with valid bit clear, rest is don't care. */ + memset(&ent, 0, sizeof(ent)); + ent.header = HASH_HEADER_EXT; + + for (i = 0; i < FCRAM_SIZE; i += sizeof(ent)) { + int err = hash_write(np, 0, i, 1, (u64 *) &ent); + if (err) + return err; + } + return 0; +} + +static int fflp_early_init(struct niu *np) +{ + struct niu_parent *parent; + unsigned long flags; + int err; + + niu_lock_parent(np, flags); + + parent = np->parent; + err = 0; + if (!(parent->flags & PARENT_FLGS_CLS_HWINIT)) { + niudbg(PROBE, "fflp_early_init: Initting hw on port %u\n", + np->port); + if (np->parent->plat_type != PLAT_TYPE_NIU) { + fflp_reset(np); + fflp_set_timings(np); + err = fflp_disable_all_partitions(np); + if (err) { + niudbg(PROBE, "fflp_disable_all_partitions " + "failed, err=%d\n", err); + goto out; + } + } + + err = tcam_early_init(np); + if (err) { + niudbg(PROBE, "tcam_early_init failed, err=%d\n", + err); + goto out; + } + fflp_llcsnap_enable(np, 1); + fflp_errors_enable(np, 0); + nw64(H1POLY, 0); + nw64(H2POLY, 0); + + err = tcam_flush_all(np); + if (err) { + niudbg(PROBE, "tcam_flush_all failed, err=%d\n", + err); + goto out; + } + if (np->parent->plat_type != PLAT_TYPE_NIU) { + err = fflp_hash_clear(np); + if (err) { + niudbg(PROBE, "fflp_hash_clear failed, " + "err=%d\n", err); + goto out; + } + } + + vlan_tbl_clear(np); + + niudbg(PROBE, "fflp_early_init: Success\n"); + parent->flags |= PARENT_FLGS_CLS_HWINIT; + } +out: + niu_unlock_parent(np, flags); + return err; +} + +static int niu_set_flow_key(struct niu *np, unsigned long class_code, u64 key) +{ + if (class_code < CLASS_CODE_USER_PROG1 || + class_code > CLASS_CODE_SCTP_IPV6) + return -EINVAL; + + nw64(FLOW_KEY(class_code - CLASS_CODE_USER_PROG1), key); + return 0; +} + +static int niu_set_tcam_key(struct niu *np, unsigned long class_code, u64 key) +{ + if (class_code < CLASS_CODE_USER_PROG1 || + class_code > CLASS_CODE_SCTP_IPV6) + return -EINVAL; + + nw64(TCAM_KEY(class_code - CLASS_CODE_USER_PROG1), key); + return 0; +} + +static void niu_rx_skb_append(struct sk_buff *skb, struct page *page, + u32 offset, u32 size) +{ + int i = skb_shinfo(skb)->nr_frags; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + frag->page = page; + frag->page_offset = offset; + frag->size = size; + + skb->len += size; + skb->data_len += size; + skb->truesize += size; + + skb_shinfo(skb)->nr_frags = i + 1; +} + +static unsigned int niu_hash_rxaddr(struct rx_ring_info *rp, u64 a) +{ + a >>= PAGE_SHIFT; + a ^= (a >> ilog2(MAX_RBR_RING_SIZE)); + + return (a & (MAX_RBR_RING_SIZE - 1)); +} + +static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr, + struct page ***link) +{ + unsigned int h = niu_hash_rxaddr(rp, addr); + struct page *p, **pp; + + addr &= PAGE_MASK; + pp = &rp->rxhash[h]; + for (; (p = *pp) != NULL; pp = (struct page **) &p->mapping) { + if (p->index == addr) { + *link = pp; + break; + } + } + + return p; +} + +static void niu_hash_page(struct rx_ring_info *rp, struct page *page, u64 base) +{ + unsigned int h = niu_hash_rxaddr(rp, base); + + page->index = base; + page->mapping = (struct address_space *) rp->rxhash[h]; + rp->rxhash[h] = page; +} + +static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp, + gfp_t mask, int start_index) +{ + struct page *page; + u64 addr; + int i; + + page = alloc_page(mask); + if (!page) + return -ENOMEM; + + addr = np->ops->map_page(np->device, page, 0, + PAGE_SIZE, DMA_FROM_DEVICE); + + niu_hash_page(rp, page, addr); + if (rp->rbr_blocks_per_page > 1) + atomic_add(rp->rbr_blocks_per_page - 1, + &compound_head(page)->_count); + + for (i = 0; i < rp->rbr_blocks_per_page; i++) { + __le32 *rbr = &rp->rbr[start_index + i]; + + *rbr = cpu_to_le32(addr >> RBR_DESCR_ADDR_SHIFT); + addr += rp->rbr_block_size; + } + + return 0; +} + +static void niu_rbr_refill(struct niu *np, struct rx_ring_info *rp, gfp_t mask) +{ + int index = rp->rbr_index; + + rp->rbr_pending++; + if ((rp->rbr_pending % rp->rbr_blocks_per_page) == 0) { + int err = niu_rbr_add_page(np, rp, mask, index); + + if (unlikely(err)) { + rp->rbr_pending--; + return; + } + + rp->rbr_index += rp->rbr_blocks_per_page; + BUG_ON(rp->rbr_index > rp->rbr_table_size); + if (rp->rbr_index == rp->rbr_table_size) + rp->rbr_index = 0; + + if (rp->rbr_pending >= rp->rbr_kick_thresh) { + nw64(RBR_KICK(rp->rx_channel), rp->rbr_pending); + rp->rbr_pending = 0; + } + } +} + +static int niu_rx_pkt_ignore(struct niu *np, struct rx_ring_info *rp) +{ + unsigned int index = rp->rcr_index; + int num_rcr = 0; + + rp->rx_dropped++; + while (1) { + struct page *page, **link; + u64 addr, val; + u32 rcr_size; + + num_rcr++; + + val = le64_to_cpup(&rp->rcr[index]); + addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << + RCR_ENTRY_PKT_BUF_ADDR_SHIFT; + page = niu_find_rxpage(rp, addr, &link); + + rcr_size = rp->rbr_sizes[(val & RCR_ENTRY_PKTBUFSZ) >> + RCR_ENTRY_PKTBUFSZ_SHIFT]; + if ((page->index + PAGE_SIZE) - rcr_size == addr) { + *link = (struct page *) page->mapping; + np->ops->unmap_page(np->device, page->index, + PAGE_SIZE, DMA_FROM_DEVICE); + page->index = 0; + page->mapping = NULL; + __free_page(page); + rp->rbr_refill_pending++; + } + + index = NEXT_RCR(rp, index); + if (!(val & RCR_ENTRY_MULTI)) + break; + + } + rp->rcr_index = index; + + return num_rcr; +} + +static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp) +{ + unsigned int index = rp->rcr_index; + struct sk_buff *skb; + int len, num_rcr; + + skb = netdev_alloc_skb(np->dev, RX_SKB_ALLOC_SIZE); + if (unlikely(!skb)) + return niu_rx_pkt_ignore(np, rp); + + num_rcr = 0; + while (1) { + struct page *page, **link; + u32 rcr_size, append_size; + u64 addr, val, off; + + num_rcr++; + + val = le64_to_cpup(&rp->rcr[index]); + + len = (val & RCR_ENTRY_L2_LEN) >> + RCR_ENTRY_L2_LEN_SHIFT; + len -= ETH_FCS_LEN; + + addr = (val & RCR_ENTRY_PKT_BUF_ADDR) << + RCR_ENTRY_PKT_BUF_ADDR_SHIFT; + page = niu_find_rxpage(rp, addr, &link); + + rcr_size = rp->rbr_sizes[(val & RCR_ENTRY_PKTBUFSZ) >> + RCR_ENTRY_PKTBUFSZ_SHIFT]; + + off = addr & ~PAGE_MASK; + append_size = rcr_size; + if (num_rcr == 1) { + int ptype; + + off += 2; + append_size -= 2; + + ptype = (val >> RCR_ENTRY_PKT_TYPE_SHIFT); + if ((ptype == RCR_PKT_TYPE_TCP || + ptype == RCR_PKT_TYPE_UDP) && + !(val & (RCR_ENTRY_NOPORT | + RCR_ENTRY_ERROR))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + } + if (!(val & RCR_ENTRY_MULTI)) + append_size = len - skb->len; + + niu_rx_skb_append(skb, page, off, append_size); + if ((page->index + rp->rbr_block_size) - rcr_size == addr) { + *link = (struct page *) page->mapping; + np->ops->unmap_page(np->device, page->index, + PAGE_SIZE, DMA_FROM_DEVICE); + page->index = 0; + page->mapping = NULL; + rp->rbr_refill_pending++; + } else + get_page(page); + + index = NEXT_RCR(rp, index); + if (!(val & RCR_ENTRY_MULTI)) + break; + + } + rp->rcr_index = index; + + skb_reserve(skb, NET_IP_ALIGN); + __pskb_pull_tail(skb, min(len, NIU_RXPULL_MAX)); + + rp->rx_packets++; + rp->rx_bytes += skb->len; + + skb->protocol = eth_type_trans(skb, np->dev); + netif_receive_skb(skb); + + return num_rcr; +} + +static int niu_rbr_fill(struct niu *np, struct rx_ring_info *rp, gfp_t mask) +{ + int blocks_per_page = rp->rbr_blocks_per_page; + int err, index = rp->rbr_index; + + err = 0; + while (index < (rp->rbr_table_size - blocks_per_page)) { + err = niu_rbr_add_page(np, rp, mask, index); + if (err) + break; + + index += blocks_per_page; + } + + rp->rbr_index = index; + return err; +} + +static void niu_rbr_free(struct niu *np, struct rx_ring_info *rp) +{ + int i; + + for (i = 0; i < MAX_RBR_RING_SIZE; i++) { + struct page *page; + + page = rp->rxhash[i]; + while (page) { + struct page *next = (struct page *) page->mapping; + u64 base = page->index; + + np->ops->unmap_page(np->device, base, PAGE_SIZE, + DMA_FROM_DEVICE); + page->index = 0; + page->mapping = NULL; + + __free_page(page); + + page = next; + } + } + + for (i = 0; i < rp->rbr_table_size; i++) + rp->rbr[i] = cpu_to_le32(0); + rp->rbr_index = 0; +} + +static int release_tx_packet(struct niu *np, struct tx_ring_info *rp, int idx) +{ + struct tx_buff_info *tb = &rp->tx_buffs[idx]; + struct sk_buff *skb = tb->skb; + struct tx_pkt_hdr *tp; + u64 tx_flags; + int i, len; + + tp = (struct tx_pkt_hdr *) skb->data; + tx_flags = le64_to_cpup(&tp->flags); + + rp->tx_packets++; + rp->tx_bytes += (((tx_flags & TXHDR_LEN) >> TXHDR_LEN_SHIFT) - + ((tx_flags & TXHDR_PAD) / 2)); + + len = skb_headlen(skb); + np->ops->unmap_single(np->device, tb->mapping, + len, DMA_TO_DEVICE); + + if (le64_to_cpu(rp->descr[idx]) & TX_DESC_MARK) + rp->mark_pending--; + + tb->skb = NULL; + do { + idx = NEXT_TX(rp, idx); + len -= MAX_TX_DESC_LEN; + } while (len > 0); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + tb = &rp->tx_buffs[idx]; + BUG_ON(tb->skb != NULL); + np->ops->unmap_page(np->device, tb->mapping, + skb_shinfo(skb)->frags[i].size, + DMA_TO_DEVICE); + idx = NEXT_TX(rp, idx); + } + + dev_kfree_skb(skb); + + return idx; +} + +#define NIU_TX_WAKEUP_THRESH(rp) ((rp)->pending / 4) + +static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) +{ + u16 pkt_cnt, tmp; + int cons; + u64 cs; + + cs = rp->tx_cs; + if (unlikely(!(cs & (TX_CS_MK | TX_CS_MMK)))) + goto out; + + tmp = pkt_cnt = (cs & TX_CS_PKT_CNT) >> TX_CS_PKT_CNT_SHIFT; + pkt_cnt = (pkt_cnt - rp->last_pkt_cnt) & + (TX_CS_PKT_CNT >> TX_CS_PKT_CNT_SHIFT); + + rp->last_pkt_cnt = tmp; + + cons = rp->cons; + + niudbg(TX_DONE, "%s: niu_tx_work() pkt_cnt[%u] cons[%d]\n", + np->dev->name, pkt_cnt, cons); + + while (pkt_cnt--) + cons = release_tx_packet(np, rp, cons); + + rp->cons = cons; + smp_mb(); + +out: + if (unlikely(netif_queue_stopped(np->dev) && + (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))) { + netif_tx_lock(np->dev); + if (netif_queue_stopped(np->dev) && + (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp))) + netif_wake_queue(np->dev); + netif_tx_unlock(np->dev); + } +} + +static int niu_rx_work(struct niu *np, struct rx_ring_info *rp, int budget) +{ + int qlen, rcr_done = 0, work_done = 0; + struct rxdma_mailbox *mbox = rp->mbox; + u64 stat; + +#if 1 + stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel)); + qlen = nr64(RCRSTAT_A(rp->rx_channel)) & RCRSTAT_A_QLEN; +#else + stat = le64_to_cpup(&mbox->rx_dma_ctl_stat); + qlen = (le64_to_cpup(&mbox->rcrstat_a) & RCRSTAT_A_QLEN); +#endif + mbox->rx_dma_ctl_stat = 0; + mbox->rcrstat_a = 0; + + niudbg(RX_STATUS, "%s: niu_rx_work(chan[%d]), stat[%llx] qlen=%d\n", + np->dev->name, rp->rx_channel, (unsigned long long) stat, qlen); + + rcr_done = work_done = 0; + qlen = min(qlen, budget); + while (work_done < qlen) { + rcr_done += niu_process_rx_pkt(np, rp); + work_done++; + } + + if (rp->rbr_refill_pending >= rp->rbr_kick_thresh) { + unsigned int i; + + for (i = 0; i < rp->rbr_refill_pending; i++) + niu_rbr_refill(np, rp, GFP_ATOMIC); + rp->rbr_refill_pending = 0; + } + + stat = (RX_DMA_CTL_STAT_MEX | + ((u64)work_done << RX_DMA_CTL_STAT_PKTREAD_SHIFT) | + ((u64)rcr_done << RX_DMA_CTL_STAT_PTRREAD_SHIFT)); + + nw64(RX_DMA_CTL_STAT(rp->rx_channel), stat); + + return work_done; +} + +static int niu_poll_core(struct niu *np, struct niu_ldg *lp, int budget) +{ + u64 v0 = lp->v0; + u32 tx_vec = (v0 >> 32); + u32 rx_vec = (v0 & 0xffffffff); + int i, work_done = 0; + + niudbg(INTR, "%s: niu_poll_core() v0[%016llx]\n", + np->dev->name, (unsigned long long) v0); + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + if (tx_vec & (1 << rp->tx_channel)) + niu_tx_work(np, rp); + nw64(LD_IM0(LDN_TXDMA(rp->tx_channel)), 0); + } + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + if (rx_vec & (1 << rp->rx_channel)) { + int this_work_done; + + this_work_done = niu_rx_work(np, rp, + budget); + + budget -= this_work_done; + work_done += this_work_done; + } + nw64(LD_IM0(LDN_RXDMA(rp->rx_channel)), 0); + } + + return work_done; +} + +#ifdef NIU_NAPI_STRUCT +static int niu_poll(struct napi_struct *napi, int budget) +{ + struct niu_ldg *lp = container_of(napi, struct niu_ldg, napi); + struct niu *np = lp->np; + int work_done; + + work_done = niu_poll_core(np, lp, budget); + + if (work_done < budget) { + netif_rx_complete(np->dev, napi); + niu_ldg_rearm(np, lp, 1); + } + return work_done; +} +#else +static int niu_poll(struct net_device *netdev, int *budget) +{ + struct niu_ldg *lp = netdev->priv; + struct niu *np = lp->np; + int work_done, orig_budget; + + orig_budget = *budget; + if (orig_budget > netdev->quota) + orig_budget = netdev->quota; + + work_done = niu_poll_core(np, lp, orig_budget); + + *budget -= work_done; + + if (work_done < orig_budget) { + netif_rx_complete(netdev); + niu_ldg_rearm(np, lp, 1); + return 0; + } + + return 1; +} +#endif + +static void niu_log_rxchan_errors(struct niu *np, struct rx_ring_info *rp, + u64 stat) +{ + dev_err(np->device, PFX "%s: RX channel %u errors ( ", + np->dev->name, rp->rx_channel); + + if (stat & RX_DMA_CTL_STAT_RBR_TMOUT) + printk("RBR_TMOUT "); + if (stat & RX_DMA_CTL_STAT_RSP_CNT_ERR) + printk("RSP_CNT "); + if (stat & RX_DMA_CTL_STAT_BYTE_EN_BUS) + printk("BYTE_EN_BUS "); + if (stat & RX_DMA_CTL_STAT_RSP_DAT_ERR) + printk("RSP_DAT "); + if (stat & RX_DMA_CTL_STAT_RCR_ACK_ERR) + printk("RCR_ACK "); + if (stat & RX_DMA_CTL_STAT_RCR_SHA_PAR) + printk("RCR_SHA_PAR "); + if (stat & RX_DMA_CTL_STAT_RBR_PRE_PAR) + printk("RBR_PRE_PAR "); + if (stat & RX_DMA_CTL_STAT_CONFIG_ERR) + printk("CONFIG "); + if (stat & RX_DMA_CTL_STAT_RCRINCON) + printk("RCRINCON "); + if (stat & RX_DMA_CTL_STAT_RCRFULL) + printk("RCRFULL "); + if (stat & RX_DMA_CTL_STAT_RBRFULL) + printk("RBRFULL "); + if (stat & RX_DMA_CTL_STAT_RBRLOGPAGE) + printk("RBRLOGPAGE "); + if (stat & RX_DMA_CTL_STAT_CFIGLOGPAGE) + printk("CFIGLOGPAGE "); + if (stat & RX_DMA_CTL_STAT_DC_FIFO_ERR) + printk("DC_FIDO "); + + printk(")\n"); +} + +static int niu_rx_error(struct niu *np, struct rx_ring_info *rp) +{ + u64 stat = nr64(RX_DMA_CTL_STAT(rp->rx_channel)); + int err = 0; + + dev_err(np->device, PFX "%s: RX channel %u error, stat[%llx]\n", + np->dev->name, rp->rx_channel, (unsigned long long) stat); + + niu_log_rxchan_errors(np, rp, stat); + + if (stat & (RX_DMA_CTL_STAT_CHAN_FATAL | + RX_DMA_CTL_STAT_PORT_FATAL)) + err = -EINVAL; + + nw64(RX_DMA_CTL_STAT(rp->rx_channel), + stat & RX_DMA_CTL_WRITE_CLEAR_ERRS); + + return err; +} + +static void niu_log_txchan_errors(struct niu *np, struct tx_ring_info *rp, + u64 cs) +{ + dev_err(np->device, PFX "%s: TX channel %u errors ( ", + np->dev->name, rp->tx_channel); + + if (cs & TX_CS_MBOX_ERR) + printk("MBOX "); + if (cs & TX_CS_PKT_SIZE_ERR) + printk("PKT_SIZE "); + if (cs & TX_CS_TX_RING_OFLOW) + printk("TX_RING_OFLOW "); + if (cs & TX_CS_PREF_BUF_PAR_ERR) + printk("PREF_BUF_PAR "); + if (cs & TX_CS_NACK_PREF) + printk("NACK_PREF "); + if (cs & TX_CS_NACK_PKT_RD) + printk("NACK_PKT_RD "); + if (cs & TX_CS_CONF_PART_ERR) + printk("CONF_PART "); + if (cs & TX_CS_PKT_PRT_ERR) + printk("PKT_PTR "); + + printk(")\n"); +} + +static int niu_tx_error(struct niu *np, struct tx_ring_info *rp) +{ + u64 cs, logh, logl; + + cs = nr64(TX_CS(rp->tx_channel)); + logh = nr64(TX_RNG_ERR_LOGH(rp->tx_channel)); + logl = nr64(TX_RNG_ERR_LOGL(rp->tx_channel)); + + dev_err(np->device, PFX "%s: TX channel %u error, " + "cs[%llx] logh[%llx] logl[%llx]\n", + np->dev->name, rp->tx_channel, + (unsigned long long) cs, + (unsigned long long) logh, + (unsigned long long) logl); + + niu_log_txchan_errors(np, rp, cs); + + return -ENODEV; +} + +static int niu_mif_interrupt(struct niu *np) +{ + u64 mif_status = nr64(MIF_STATUS); + int phy_mdint = 0; + + if (np->flags & NIU_FLAGS_XMAC) { + u64 xrxmac_stat = nr64_mac(XRXMAC_STATUS); + + if (xrxmac_stat & XRXMAC_STATUS_PHY_MDINT) + phy_mdint = 1; + } + + dev_err(np->device, PFX "%s: MIF interrupt, " + "stat[%llx] phy_mdint(%d)\n", + np->dev->name, (unsigned long long) mif_status, phy_mdint); + + return -ENODEV; +} + +static void niu_xmac_interrupt(struct niu *np) +{ + struct niu_xmac_stats *mp = &np->mac_stats.xmac; + u64 val; + + val = nr64_mac(XTXMAC_STATUS); + if (val & XTXMAC_STATUS_FRAME_CNT_EXP) + mp->tx_frames += TXMAC_FRM_CNT_COUNT; + if (val & XTXMAC_STATUS_BYTE_CNT_EXP) + mp->tx_bytes += TXMAC_BYTE_CNT_COUNT; + if (val & XTXMAC_STATUS_TXFIFO_XFR_ERR) + mp->tx_fifo_errors++; + if (val & XTXMAC_STATUS_TXMAC_OFLOW) + mp->tx_overflow_errors++; + if (val & XTXMAC_STATUS_MAX_PSIZE_ERR) + mp->tx_max_pkt_size_errors++; + if (val & XTXMAC_STATUS_TXMAC_UFLOW) + mp->tx_underflow_errors++; + + val = nr64_mac(XRXMAC_STATUS); + if (val & XRXMAC_STATUS_LCL_FLT_STATUS) + mp->rx_local_faults++; + if (val & XRXMAC_STATUS_RFLT_DET) + mp->rx_remote_faults++; + if (val & XRXMAC_STATUS_LFLT_CNT_EXP) + mp->rx_link_faults += LINK_FAULT_CNT_COUNT; + if (val & XRXMAC_STATUS_ALIGNERR_CNT_EXP) + mp->rx_align_errors += RXMAC_ALIGN_ERR_CNT_COUNT; + if (val & XRXMAC_STATUS_RXFRAG_CNT_EXP) + mp->rx_frags += RXMAC_FRAG_CNT_COUNT; + if (val & XRXMAC_STATUS_RXMULTF_CNT_EXP) + mp->rx_mcasts += RXMAC_MC_FRM_CNT_COUNT; + if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) + mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; + if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) + mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; + if (val & XRXMAC_STATUS_RXHIST1_CNT_EXP) + mp->rx_hist_cnt1 += RXMAC_HIST_CNT1_COUNT; + if (val & XRXMAC_STATUS_RXHIST2_CNT_EXP) + mp->rx_hist_cnt2 += RXMAC_HIST_CNT2_COUNT; + if (val & XRXMAC_STATUS_RXHIST3_CNT_EXP) + mp->rx_hist_cnt3 += RXMAC_HIST_CNT3_COUNT; + if (val & XRXMAC_STATUS_RXHIST4_CNT_EXP) + mp->rx_hist_cnt4 += RXMAC_HIST_CNT4_COUNT; + if (val & XRXMAC_STATUS_RXHIST5_CNT_EXP) + mp->rx_hist_cnt5 += RXMAC_HIST_CNT5_COUNT; + if (val & XRXMAC_STATUS_RXHIST6_CNT_EXP) + mp->rx_hist_cnt6 += RXMAC_HIST_CNT6_COUNT; + if (val & XRXMAC_STATUS_RXHIST7_CNT_EXP) + mp->rx_hist_cnt7 += RXMAC_HIST_CNT7_COUNT; + if (val & XRXMAC_STAT_MSK_RXOCTET_CNT_EXP) + mp->rx_octets += RXMAC_BT_CNT_COUNT; + if (val & XRXMAC_STATUS_CVIOLERR_CNT_EXP) + mp->rx_code_violations += RXMAC_CD_VIO_CNT_COUNT; + if (val & XRXMAC_STATUS_LENERR_CNT_EXP) + mp->rx_len_errors += RXMAC_MPSZER_CNT_COUNT; + if (val & XRXMAC_STATUS_CRCERR_CNT_EXP) + mp->rx_crc_errors += RXMAC_CRC_ER_CNT_COUNT; + if (val & XRXMAC_STATUS_RXUFLOW) + mp->rx_underflows++; + if (val & XRXMAC_STATUS_RXOFLOW) + mp->rx_overflows++; + + val = nr64_mac(XMAC_FC_STAT); + if (val & XMAC_FC_STAT_TX_MAC_NPAUSE) + mp->pause_off_state++; + if (val & XMAC_FC_STAT_TX_MAC_PAUSE) + mp->pause_on_state++; + if (val & XMAC_FC_STAT_RX_MAC_RPAUSE) + mp->pause_received++; +} + +static void niu_bmac_interrupt(struct niu *np) +{ + struct niu_bmac_stats *mp = &np->mac_stats.bmac; + u64 val; + + val = nr64_mac(BTXMAC_STATUS); + if (val & BTXMAC_STATUS_UNDERRUN) + mp->tx_underflow_errors++; + if (val & BTXMAC_STATUS_MAX_PKT_ERR) + mp->tx_max_pkt_size_errors++; + if (val & BTXMAC_STATUS_BYTE_CNT_EXP) + mp->tx_bytes += BTXMAC_BYTE_CNT_COUNT; + if (val & BTXMAC_STATUS_FRAME_CNT_EXP) + mp->tx_frames += BTXMAC_FRM_CNT_COUNT; + + val = nr64_mac(BRXMAC_STATUS); + if (val & BRXMAC_STATUS_OVERFLOW) + mp->rx_overflows++; + if (val & BRXMAC_STATUS_FRAME_CNT_EXP) + mp->rx_frames += BRXMAC_FRAME_CNT_COUNT; + if (val & BRXMAC_STATUS_ALIGN_ERR_EXP) + mp->rx_align_errors += BRXMAC_ALIGN_ERR_CNT_COUNT; + if (val & BRXMAC_STATUS_CRC_ERR_EXP) + mp->rx_crc_errors += BRXMAC_ALIGN_ERR_CNT_COUNT; + if (val & BRXMAC_STATUS_LEN_ERR_EXP) + mp->rx_len_errors += BRXMAC_CODE_VIOL_ERR_CNT_COUNT; + + val = nr64_mac(BMAC_CTRL_STATUS); + if (val & BMAC_CTRL_STATUS_NOPAUSE) + mp->pause_off_state++; + if (val & BMAC_CTRL_STATUS_PAUSE) + mp->pause_on_state++; + if (val & BMAC_CTRL_STATUS_PAUSE_RECV) + mp->pause_received++; +} + +static int niu_mac_interrupt(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_xmac_interrupt(np); + else + niu_bmac_interrupt(np); + + return 0; +} + +static void niu_log_device_error(struct niu *np, u64 stat) +{ + dev_err(np->device, PFX "%s: Core device errors ( ", + np->dev->name); + + if (stat & SYS_ERR_MASK_META2) + printk("META2 "); + if (stat & SYS_ERR_MASK_META1) + printk("META1 "); + if (stat & SYS_ERR_MASK_PEU) + printk("PEU "); + if (stat & SYS_ERR_MASK_TXC) + printk("TXC "); + if (stat & SYS_ERR_MASK_RDMC) + printk("RDMC "); + if (stat & SYS_ERR_MASK_TDMC) + printk("TDMC "); + if (stat & SYS_ERR_MASK_ZCP) + printk("ZCP "); + if (stat & SYS_ERR_MASK_FFLP) + printk("FFLP "); + if (stat & SYS_ERR_MASK_IPP) + printk("IPP "); + if (stat & SYS_ERR_MASK_MAC) + printk("MAC "); + if (stat & SYS_ERR_MASK_SMX) + printk("SMX "); + + printk(")\n"); +} + +static int niu_device_error(struct niu *np) +{ + u64 stat = nr64(SYS_ERR_STAT); + + dev_err(np->device, PFX "%s: Core device error, stat[%llx]\n", + np->dev->name, (unsigned long long) stat); + + niu_log_device_error(np, stat); + + return -ENODEV; +} + +static int niu_slowpath_interrupt(struct niu *np, struct niu_ldg *lp) +{ + u64 v0 = lp->v0; + u64 v1 = lp->v1; + u64 v2 = lp->v2; + int i, err = 0; + + if (v1 & 0x00000000ffffffffULL) { + u32 rx_vec = (v1 & 0xffffffff); + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + if (rx_vec & (1 << rp->rx_channel)) { + int r = niu_rx_error(np, rp); + if (r) + err = r; + } + } + } + if (v1 & 0x7fffffff00000000ULL) { + u32 tx_vec = (v1 >> 32) & 0x7fffffff; + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + if (tx_vec & (1 << rp->tx_channel)) { + int r = niu_tx_error(np, rp); + if (r) + err = r; + } + } + } + if ((v0 | v1) & 0x8000000000000000ULL) { + int r = niu_mif_interrupt(np); + if (r) + err = r; + } + if (v2) { + if (v2 & 0x01ef) { + int r = niu_mac_interrupt(np); + if (r) + err = r; + } + if (v2 & 0x0210) { + int r = niu_device_error(np); + if (r) + err = r; + } + } + + if (err) + niu_enable_interrupts(np, 0); + + return -EINVAL; +} + +static void niu_rxchan_intr(struct niu *np, struct rx_ring_info *rp, + int ldn) +{ + struct rxdma_mailbox *mbox = rp->mbox; + u64 stat_write, stat = le64_to_cpup(&mbox->rx_dma_ctl_stat); + + stat_write = (RX_DMA_CTL_STAT_RCRTHRES | + RX_DMA_CTL_STAT_RCRTO); + nw64(RX_DMA_CTL_STAT(rp->rx_channel), stat_write); + + niudbg(INTR, "%s: rxchan_intr stat[%llx]\n", + np->dev->name, (unsigned long long) stat); +} + +static void niu_txchan_intr(struct niu *np, struct tx_ring_info *rp, + int ldn) +{ + rp->tx_cs = nr64(TX_CS(rp->tx_channel)); + + niudbg(INTR, "%s: txchan_intr cs[%llx]\n", + np->dev->name, (unsigned long long) rp->tx_cs); +} + +static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0) +{ + struct niu_parent *parent = np->parent; + u32 rx_vec, tx_vec; + int i; + + tx_vec = (v0 >> 32); + rx_vec = (v0 & 0xffffffff); + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + int ldn = LDN_RXDMA(rp->rx_channel); + + if (parent->ldg_map[ldn] != ldg) + continue; + + nw64(LD_IM0(ldn), LD_IM0_MASK); + if (rx_vec & (1 << rp->rx_channel)) + niu_rxchan_intr(np, rp, ldn); + } + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + int ldn = LDN_TXDMA(rp->tx_channel); + + if (parent->ldg_map[ldn] != ldg) + continue; + + nw64(LD_IM0(ldn), LD_IM0_MASK); + if (tx_vec & (1 << rp->tx_channel)) + niu_txchan_intr(np, rp, ldn); + } +} + +#ifdef NIU_NAPI_STRUCT +static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp, + u64 v0, u64 v1, u64 v2) +{ + if (likely(netif_rx_schedule_prep(np->dev, &lp->napi))) { + lp->v0 = v0; + lp->v1 = v1; + lp->v2 = v2; + __niu_fastpath_interrupt(np, lp->ldg_num, v0); + __netif_rx_schedule(np->dev, &lp->napi); + } +} +#else +static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp, + u64 v0, u64 v1, u64 v2) +{ + if (likely(netif_rx_schedule_prep(lp->dummy_netdev))) { + lp->v0 = v0; + lp->v1 = v1; + lp->v2 = v2; + __niu_fastpath_interrupt(np, lp->ldg_num, v0); + __netif_rx_schedule(lp->dummy_netdev); + } +} +#endif + +static irqreturn_t niu_interrupt(int irq, void *dev_id) +{ + struct niu_ldg *lp = dev_id; + struct niu *np = lp->np; + int ldg = lp->ldg_num; + unsigned long flags; + u64 v0, v1, v2; + + if (netif_msg_intr(np)) + printk(KERN_DEBUG PFX "niu_interrupt() ldg[%p](%d) ", + lp, ldg); + + spin_lock_irqsave(&np->lock, flags); + + v0 = nr64(LDSV0(ldg)); + v1 = nr64(LDSV1(ldg)); + v2 = nr64(LDSV2(ldg)); + + if (netif_msg_intr(np)) + printk("v0[%llx] v1[%llx] v2[%llx]\n", + (unsigned long long) v0, + (unsigned long long) v1, + (unsigned long long) v2); + + if (unlikely(!v0 && !v1 && !v2)) { + spin_unlock_irqrestore(&np->lock, flags); + return IRQ_NONE; + } + + if (unlikely((v0 & ((u64)1 << LDN_MIF)) || v1 || v2)) { + int err = niu_slowpath_interrupt(np, lp); + if (err) + goto out; + } + if (likely(v0 & ~((u64)1 << LDN_MIF))) + niu_schedule_napi(np, lp, v0, v1, v2); + else + niu_ldg_rearm(np, lp, 1); +out: + spin_unlock_irqrestore(&np->lock, flags); + + return IRQ_HANDLED; +} + +static void niu_free_rx_ring_info(struct niu *np, struct rx_ring_info *rp) +{ + if (rp->mbox) { + np->ops->free_coherent(np->device, + sizeof(struct rxdma_mailbox), + rp->mbox, rp->mbox_dma); + rp->mbox = NULL; + } + if (rp->rcr) { + np->ops->free_coherent(np->device, + MAX_RCR_RING_SIZE * sizeof(__le64), + rp->rcr, rp->rcr_dma); + rp->rcr = NULL; + rp->rcr_table_size = 0; + rp->rcr_index = 0; + } + if (rp->rbr) { + niu_rbr_free(np, rp); + + np->ops->free_coherent(np->device, + MAX_RBR_RING_SIZE * sizeof(__le32), + rp->rbr, rp->rbr_dma); + rp->rbr = NULL; + rp->rbr_table_size = 0; + rp->rbr_index = 0; + } + kfree(rp->rxhash); + rp->rxhash = NULL; +} + +static void niu_free_tx_ring_info(struct niu *np, struct tx_ring_info *rp) +{ + if (rp->mbox) { + np->ops->free_coherent(np->device, + sizeof(struct txdma_mailbox), + rp->mbox, rp->mbox_dma); + rp->mbox = NULL; + } + if (rp->descr) { + int i; + + for (i = 0; i < MAX_TX_RING_SIZE; i++) { + if (rp->tx_buffs[i].skb) + (void) release_tx_packet(np, rp, i); + } + + np->ops->free_coherent(np->device, + MAX_TX_RING_SIZE * sizeof(__le64), + rp->descr, rp->descr_dma); + rp->descr = NULL; + rp->pending = 0; + rp->prod = 0; + rp->cons = 0; + rp->wrap_bit = 0; + } +} + +static void niu_free_channels(struct niu *np) +{ + int i; + + if (np->rx_rings) { + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + niu_free_rx_ring_info(np, rp); + } + kfree(np->rx_rings); + np->rx_rings = NULL; + np->num_rx_rings = 0; + } + + if (np->tx_rings) { + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + niu_free_tx_ring_info(np, rp); + } + kfree(np->tx_rings); + np->tx_rings = NULL; + np->num_tx_rings = 0; + } +} + +static int niu_alloc_rx_ring_info(struct niu *np, + struct rx_ring_info *rp) +{ + BUILD_BUG_ON(sizeof(struct rxdma_mailbox) != 64); + + rp->rxhash = kzalloc(MAX_RBR_RING_SIZE * sizeof(struct page *), + GFP_KERNEL); + if (!rp->rxhash) + return -ENOMEM; + + rp->mbox = np->ops->alloc_coherent(np->device, + sizeof(struct rxdma_mailbox), + &rp->mbox_dma, GFP_KERNEL); + if (!rp->mbox) + return -ENOMEM; + if ((unsigned long)rp->mbox & (64UL - 1)) { + dev_err(np->device, PFX "%s: Coherent alloc gives misaligned " + "RXDMA mailbox %p\n", np->dev->name, rp->mbox); + return -EINVAL; + } + + rp->rcr = np->ops->alloc_coherent(np->device, + MAX_RCR_RING_SIZE * sizeof(__le64), + &rp->rcr_dma, GFP_KERNEL); + if (!rp->rcr) + return -ENOMEM; + if ((unsigned long)rp->rcr & (64UL - 1)) { + dev_err(np->device, PFX "%s: Coherent alloc gives misaligned " + "RXDMA RCR table %p\n", np->dev->name, rp->rcr); + return -EINVAL; + } + rp->rcr_table_size = MAX_RCR_RING_SIZE; + rp->rcr_index = 0; + + rp->rbr = np->ops->alloc_coherent(np->device, + MAX_RBR_RING_SIZE * sizeof(__le32), + &rp->rbr_dma, GFP_KERNEL); + if (!rp->rbr) + return -ENOMEM; + if ((unsigned long)rp->rbr & (64UL - 1)) { + dev_err(np->device, PFX "%s: Coherent alloc gives misaligned " + "RXDMA RBR table %p\n", np->dev->name, rp->rbr); + return -EINVAL; + } + rp->rbr_table_size = MAX_RBR_RING_SIZE; + rp->rbr_index = 0; + rp->rbr_pending = 0; + + return 0; +} + +static void niu_set_max_burst(struct niu *np, struct tx_ring_info *rp) +{ + int mtu = np->dev->mtu; + + /* These values are recommended by the HW designers for fair + * utilization of DRR amongst the rings. + */ + rp->max_burst = mtu + 32; + if (rp->max_burst > 4096) + rp->max_burst = 4096; +} + +static int niu_alloc_tx_ring_info(struct niu *np, + struct tx_ring_info *rp) +{ + BUILD_BUG_ON(sizeof(struct txdma_mailbox) != 64); + + rp->mbox = np->ops->alloc_coherent(np->device, + sizeof(struct txdma_mailbox), + &rp->mbox_dma, GFP_KERNEL); + if (!rp->mbox) + return -ENOMEM; + if ((unsigned long)rp->mbox & (64UL - 1)) { + dev_err(np->device, PFX "%s: Coherent alloc gives misaligned " + "TXDMA mailbox %p\n", np->dev->name, rp->mbox); + return -EINVAL; + } + + rp->descr = np->ops->alloc_coherent(np->device, + MAX_TX_RING_SIZE * sizeof(__le64), + &rp->descr_dma, GFP_KERNEL); + if (!rp->descr) + return -ENOMEM; + if ((unsigned long)rp->descr & (64UL - 1)) { + dev_err(np->device, PFX "%s: Coherent alloc gives misaligned " + "TXDMA descr table %p\n", np->dev->name, rp->descr); + return -EINVAL; + } + + rp->pending = MAX_TX_RING_SIZE; + rp->prod = 0; + rp->cons = 0; + rp->wrap_bit = 0; + + /* XXX make these configurable... XXX */ + rp->mark_freq = rp->pending / 4; + + niu_set_max_burst(np, rp); + + return 0; +} + +static void niu_size_rbr(struct niu *np, struct rx_ring_info *rp) +{ + u16 bs; + + switch (PAGE_SIZE) { + case 4 * 1024: + case 8 * 1024: + case 16 * 1024: + case 32 * 1024: + rp->rbr_block_size = PAGE_SIZE; + rp->rbr_blocks_per_page = 1; + break; + + default: + if (PAGE_SIZE % (32 * 1024) == 0) + bs = 32 * 1024; + else if (PAGE_SIZE % (16 * 1024) == 0) + bs = 16 * 1024; + else if (PAGE_SIZE % (8 * 1024) == 0) + bs = 8 * 1024; + else if (PAGE_SIZE % (4 * 1024) == 0) + bs = 4 * 1024; + else + BUG(); + rp->rbr_block_size = bs; + rp->rbr_blocks_per_page = PAGE_SIZE / bs; + } + + rp->rbr_sizes[0] = 256; + rp->rbr_sizes[1] = 1024; + if (np->dev->mtu > ETH_DATA_LEN) { + switch (PAGE_SIZE) { + case 4 * 1024: + rp->rbr_sizes[2] = 4096; + break; + + default: + rp->rbr_sizes[2] = 8192; + break; + } + } else { + rp->rbr_sizes[2] = 2048; + } + rp->rbr_sizes[3] = rp->rbr_block_size; +} + +static int niu_alloc_channels(struct niu *np) +{ + struct niu_parent *parent = np->parent; + int first_rx_channel, first_tx_channel; + int i, port, err; + + port = np->port; + first_rx_channel = first_tx_channel = 0; + for (i = 0; i < port; i++) { + first_rx_channel += parent->rxchan_per_port[i]; + first_tx_channel += parent->txchan_per_port[i]; + } + + np->num_rx_rings = parent->rxchan_per_port[port]; + np->num_tx_rings = parent->txchan_per_port[port]; + + np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info), + GFP_KERNEL); + err = -ENOMEM; + if (!np->rx_rings) + goto out_err; + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + rp->np = np; + rp->rx_channel = first_rx_channel + i; + + err = niu_alloc_rx_ring_info(np, rp); + if (err) + goto out_err; + + niu_size_rbr(np, rp); + + /* XXX better defaults, configurable, etc... XXX */ + rp->nonsyn_window = 64; + rp->nonsyn_threshold = rp->rcr_table_size - 64; + rp->syn_window = 64; + rp->syn_threshold = rp->rcr_table_size - 64; + rp->rcr_pkt_threshold = 16; + rp->rcr_timeout = 8; + rp->rbr_kick_thresh = RBR_REFILL_MIN; + if (rp->rbr_kick_thresh < rp->rbr_blocks_per_page) + rp->rbr_kick_thresh = rp->rbr_blocks_per_page; + + err = niu_rbr_fill(np, rp, GFP_KERNEL); + if (err) + return err; + } + + np->tx_rings = kzalloc(np->num_tx_rings * sizeof(struct tx_ring_info), + GFP_KERNEL); + err = -ENOMEM; + if (!np->tx_rings) + goto out_err; + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + rp->np = np; + rp->tx_channel = first_tx_channel + i; + + err = niu_alloc_tx_ring_info(np, rp); + if (err) + goto out_err; + } + + return 0; + +out_err: + niu_free_channels(np); + return err; +} + +static int niu_tx_cs_sng_poll(struct niu *np, int channel) +{ + int limit = 1000; + + while (--limit > 0) { + u64 val = nr64(TX_CS(channel)); + if (val & TX_CS_SNG_STATE) + return 0; + } + return -ENODEV; +} + +static int niu_tx_channel_stop(struct niu *np, int channel) +{ + u64 val = nr64(TX_CS(channel)); + + val |= TX_CS_STOP_N_GO; + nw64(TX_CS(channel), val); + + return niu_tx_cs_sng_poll(np, channel); +} + +static int niu_tx_cs_reset_poll(struct niu *np, int channel) +{ + int limit = 1000; + + while (--limit > 0) { + u64 val = nr64(TX_CS(channel)); + if (!(val & TX_CS_RST)) + return 0; + } + return -ENODEV; +} + +static int niu_tx_channel_reset(struct niu *np, int channel) +{ + u64 val = nr64(TX_CS(channel)); + int err; + + val |= TX_CS_RST; + nw64(TX_CS(channel), val); + + err = niu_tx_cs_reset_poll(np, channel); + if (!err) + nw64(TX_RING_KICK(channel), 0); + + return err; +} + +static int niu_tx_channel_lpage_init(struct niu *np, int channel) +{ + u64 val; + + nw64(TX_LOG_MASK1(channel), 0); + nw64(TX_LOG_VAL1(channel), 0); + nw64(TX_LOG_MASK2(channel), 0); + nw64(TX_LOG_VAL2(channel), 0); + nw64(TX_LOG_PAGE_RELO1(channel), 0); + nw64(TX_LOG_PAGE_RELO2(channel), 0); + nw64(TX_LOG_PAGE_HDL(channel), 0); + + val = (u64)np->port << TX_LOG_PAGE_VLD_FUNC_SHIFT; + val |= (TX_LOG_PAGE_VLD_PAGE0 | TX_LOG_PAGE_VLD_PAGE1); + nw64(TX_LOG_PAGE_VLD(channel), val); + + /* XXX TXDMA 32bit mode? XXX */ + + return 0; +} + +static void niu_txc_enable_port(struct niu *np, int on) +{ + unsigned long flags; + u64 val, mask; + + niu_lock_parent(np, flags); + val = nr64(TXC_CONTROL); + mask = (u64)1 << np->port; + if (on) { + val |= TXC_CONTROL_ENABLE | mask; + } else { + val &= ~mask; + if ((val & ~TXC_CONTROL_ENABLE) == 0) + val &= ~TXC_CONTROL_ENABLE; + } + nw64(TXC_CONTROL, val); + niu_unlock_parent(np, flags); +} + +static void niu_txc_set_imask(struct niu *np, u64 imask) +{ + unsigned long flags; + u64 val; + + niu_lock_parent(np, flags); + val = nr64(TXC_INT_MASK); + val &= ~TXC_INT_MASK_VAL(np->port); + val |= (imask << TXC_INT_MASK_VAL_SHIFT(np->port)); + niu_unlock_parent(np, flags); +} + +static void niu_txc_port_dma_enable(struct niu *np, int on) +{ + u64 val = 0; + + if (on) { + int i; + + for (i = 0; i < np->num_tx_rings; i++) + val |= (1 << np->tx_rings[i].tx_channel); + } + nw64(TXC_PORT_DMA(np->port), val); +} + +static int niu_init_one_tx_channel(struct niu *np, struct tx_ring_info *rp) +{ + int err, channel = rp->tx_channel; + u64 val, ring_len; + + err = niu_tx_channel_stop(np, channel); + if (err) + return err; + + err = niu_tx_channel_reset(np, channel); + if (err) + return err; + + err = niu_tx_channel_lpage_init(np, channel); + if (err) + return err; + + nw64(TXC_DMA_MAX(channel), rp->max_burst); + nw64(TX_ENT_MSK(channel), 0); + + if (rp->descr_dma & ~(TX_RNG_CFIG_STADDR_BASE | + TX_RNG_CFIG_STADDR)) { + dev_err(np->device, PFX "%s: TX ring channel %d " + "DMA addr (%llx) is not aligned.\n", + np->dev->name, channel, + (unsigned long long) rp->descr_dma); + return -EINVAL; + } + + /* The length field in TX_RNG_CFIG is measured in 64-byte + * blocks. rp->pending is the number of TX descriptors in + * our ring, 8 bytes each, thus we divide by 8 bytes more + * to get the proper value the chip wants. + */ + ring_len = (rp->pending / 8); + + val = ((ring_len << TX_RNG_CFIG_LEN_SHIFT) | + rp->descr_dma); + nw64(TX_RNG_CFIG(channel), val); + + if (((rp->mbox_dma >> 32) & ~TXDMA_MBH_MBADDR) || + ((u32)rp->mbox_dma & ~TXDMA_MBL_MBADDR)) { + dev_err(np->device, PFX "%s: TX ring channel %d " + "MBOX addr (%llx) is has illegal bits.\n", + np->dev->name, channel, + (unsigned long long) rp->mbox_dma); + return -EINVAL; + } + nw64(TXDMA_MBH(channel), rp->mbox_dma >> 32); + nw64(TXDMA_MBL(channel), rp->mbox_dma & TXDMA_MBL_MBADDR); + + nw64(TX_CS(channel), 0); + + rp->last_pkt_cnt = 0; + + return 0; +} + +static void niu_init_rdc_groups(struct niu *np) +{ + struct niu_rdc_tables *tp = &np->parent->rdc_group_cfg[np->port]; + int i, first_table_num = tp->first_table_num; + + for (i = 0; i < tp->num_tables; i++) { + struct rdc_table *tbl = &tp->tables[i]; + int this_table = first_table_num + i; + int slot; + + for (slot = 0; slot < NIU_RDC_TABLE_SLOTS; slot++) + nw64(RDC_TBL(this_table, slot), + tbl->rxdma_channel[slot]); + } + + nw64(DEF_RDC(np->port), np->parent->rdc_default[np->port]); +} + +static void niu_init_drr_weight(struct niu *np) +{ + int type = phy_decode(np->parent->port_phy, np->port); + u64 val; + + switch (type) { + case PORT_TYPE_10G: + val = PT_DRR_WEIGHT_DEFAULT_10G; + break; + + case PORT_TYPE_1G: + default: + val = PT_DRR_WEIGHT_DEFAULT_1G; + break; + } + nw64(PT_DRR_WT(np->port), val); +} + +static int niu_init_hostinfo(struct niu *np) +{ + struct niu_parent *parent = np->parent; + struct niu_rdc_tables *tp = &parent->rdc_group_cfg[np->port]; + int i, err, num_alt = niu_num_alt_addr(np); + int first_rdc_table = tp->first_table_num; + + err = niu_set_primary_mac_rdc_table(np, first_rdc_table, 1); + if (err) + return err; + + err = niu_set_multicast_mac_rdc_table(np, first_rdc_table, 1); + if (err) + return err; + + for (i = 0; i < num_alt; i++) { + err = niu_set_alt_mac_rdc_table(np, i, first_rdc_table, 1); + if (err) + return err; + } + + return 0; +} + +static int niu_rx_channel_reset(struct niu *np, int channel) +{ + return niu_set_and_wait_clear(np, RXDMA_CFIG1(channel), + RXDMA_CFIG1_RST, 1000, 10, + "RXDMA_CFIG1"); +} + +static int niu_rx_channel_lpage_init(struct niu *np, int channel) +{ + u64 val; + + nw64(RX_LOG_MASK1(channel), 0); + nw64(RX_LOG_VAL1(channel), 0); + nw64(RX_LOG_MASK2(channel), 0); + nw64(RX_LOG_VAL2(channel), 0); + nw64(RX_LOG_PAGE_RELO1(channel), 0); + nw64(RX_LOG_PAGE_RELO2(channel), 0); + nw64(RX_LOG_PAGE_HDL(channel), 0); + + val = (u64)np->port << RX_LOG_PAGE_VLD_FUNC_SHIFT; + val |= (RX_LOG_PAGE_VLD_PAGE0 | RX_LOG_PAGE_VLD_PAGE1); + nw64(RX_LOG_PAGE_VLD(channel), val); + + return 0; +} + +static void niu_rx_channel_wred_init(struct niu *np, struct rx_ring_info *rp) +{ + u64 val; + + val = (((u64)rp->nonsyn_window << RDC_RED_PARA_WIN_SHIFT) | + ((u64)rp->nonsyn_threshold << RDC_RED_PARA_THRE_SHIFT) | + ((u64)rp->syn_window << RDC_RED_PARA_WIN_SYN_SHIFT) | + ((u64)rp->syn_threshold << RDC_RED_PARA_THRE_SYN_SHIFT)); + nw64(RDC_RED_PARA(rp->rx_channel), val); +} + +static int niu_compute_rbr_cfig_b(struct rx_ring_info *rp, u64 *ret) +{ + u64 val = 0; + + switch (rp->rbr_block_size) { + case 4 * 1024: + val |= (RBR_BLKSIZE_4K << RBR_CFIG_B_BLKSIZE_SHIFT); + break; + case 8 * 1024: + val |= (RBR_BLKSIZE_8K << RBR_CFIG_B_BLKSIZE_SHIFT); + break; + case 16 * 1024: + val |= (RBR_BLKSIZE_16K << RBR_CFIG_B_BLKSIZE_SHIFT); + break; + case 32 * 1024: + val |= (RBR_BLKSIZE_32K << RBR_CFIG_B_BLKSIZE_SHIFT); + break; + default: + return -EINVAL; + } + val |= RBR_CFIG_B_VLD2; + switch (rp->rbr_sizes[2]) { + case 2 * 1024: + val |= (RBR_BUFSZ2_2K << RBR_CFIG_B_BUFSZ2_SHIFT); + break; + case 4 * 1024: + val |= (RBR_BUFSZ2_4K << RBR_CFIG_B_BUFSZ2_SHIFT); + break; + case 8 * 1024: + val |= (RBR_BUFSZ2_8K << RBR_CFIG_B_BUFSZ2_SHIFT); + break; + case 16 * 1024: + val |= (RBR_BUFSZ2_16K << RBR_CFIG_B_BUFSZ2_SHIFT); + break; + + default: + return -EINVAL; + } + val |= RBR_CFIG_B_VLD1; + switch (rp->rbr_sizes[1]) { + case 1 * 1024: + val |= (RBR_BUFSZ1_1K << RBR_CFIG_B_BUFSZ1_SHIFT); + break; + case 2 * 1024: + val |= (RBR_BUFSZ1_2K << RBR_CFIG_B_BUFSZ1_SHIFT); + break; + case 4 * 1024: + val |= (RBR_BUFSZ1_4K << RBR_CFIG_B_BUFSZ1_SHIFT); + break; + case 8 * 1024: + val |= (RBR_BUFSZ1_8K << RBR_CFIG_B_BUFSZ1_SHIFT); + break; + + default: + return -EINVAL; + } + val |= RBR_CFIG_B_VLD0; + switch (rp->rbr_sizes[0]) { + case 256: + val |= (RBR_BUFSZ0_256 << RBR_CFIG_B_BUFSZ0_SHIFT); + break; + case 512: + val |= (RBR_BUFSZ0_512 << RBR_CFIG_B_BUFSZ0_SHIFT); + break; + case 1 * 1024: + val |= (RBR_BUFSZ0_1K << RBR_CFIG_B_BUFSZ0_SHIFT); + break; + case 2 * 1024: + val |= (RBR_BUFSZ0_2K << RBR_CFIG_B_BUFSZ0_SHIFT); + break; + + default: + return -EINVAL; + } + + *ret = val; + return 0; +} + +static int niu_enable_rx_channel(struct niu *np, int channel, int on) +{ + u64 val = nr64(RXDMA_CFIG1(channel)); + int limit; + + if (on) + val |= RXDMA_CFIG1_EN; + else + val &= ~RXDMA_CFIG1_EN; + nw64(RXDMA_CFIG1(channel), val); + + limit = 1000; + while (--limit > 0) { + if (nr64(RXDMA_CFIG1(channel)) & RXDMA_CFIG1_QST) + break; + udelay(10); + } + if (limit <= 0) + return -ENODEV; + return 0; +} + +static int niu_init_one_rx_channel(struct niu *np, struct rx_ring_info *rp) +{ + int err, channel = rp->rx_channel; + u64 val; + + err = niu_rx_channel_reset(np, channel); + if (err) + return err; + + err = niu_rx_channel_lpage_init(np, channel); + if (err) + return err; + + niu_rx_channel_wred_init(np, rp); + + nw64(RX_DMA_ENT_MSK(channel), RX_DMA_ENT_MSK_RBR_EMPTY); + nw64(RX_DMA_CTL_STAT(channel), + (RX_DMA_CTL_STAT_MEX | + RX_DMA_CTL_STAT_RCRTHRES | + RX_DMA_CTL_STAT_RCRTO | + RX_DMA_CTL_STAT_RBR_EMPTY)); + nw64(RXDMA_CFIG1(channel), rp->mbox_dma >> 32); + nw64(RXDMA_CFIG2(channel), (rp->mbox_dma & 0x00000000ffffffc0)); + nw64(RBR_CFIG_A(channel), + ((u64)rp->rbr_table_size << RBR_CFIG_A_LEN_SHIFT) | + (rp->rbr_dma & (RBR_CFIG_A_STADDR_BASE | RBR_CFIG_A_STADDR))); + err = niu_compute_rbr_cfig_b(rp, &val); + if (err) + return err; + nw64(RBR_CFIG_B(channel), val); + nw64(RCRCFIG_A(channel), + ((u64)rp->rcr_table_size << RCRCFIG_A_LEN_SHIFT) | + (rp->rcr_dma & (RCRCFIG_A_STADDR_BASE | RCRCFIG_A_STADDR))); + nw64(RCRCFIG_B(channel), + ((u64)rp->rcr_pkt_threshold << RCRCFIG_B_PTHRES_SHIFT) | + RCRCFIG_B_ENTOUT | + ((u64)rp->rcr_timeout << RCRCFIG_B_TIMEOUT_SHIFT)); + + err = niu_enable_rx_channel(np, channel, 1); + if (err) + return err; + + nw64(RBR_KICK(channel), rp->rbr_index); + + val = nr64(RX_DMA_CTL_STAT(channel)); + val |= RX_DMA_CTL_STAT_RBR_EMPTY; + nw64(RX_DMA_CTL_STAT(channel), val); + + return 0; +} + +static int niu_init_rx_channels(struct niu *np) +{ + unsigned long flags; + u64 seed = jiffies_64; + int err, i; + + niu_lock_parent(np, flags); + nw64(RX_DMA_CK_DIV, np->parent->rxdma_clock_divider); + nw64(RED_RAN_INIT, RED_RAN_INIT_OPMODE | (seed & RED_RAN_INIT_VAL)); + niu_unlock_parent(np, flags); + + /* XXX RXDMA 32bit mode? XXX */ + + niu_init_rdc_groups(np); + niu_init_drr_weight(np); + + err = niu_init_hostinfo(np); + if (err) + return err; + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + err = niu_init_one_rx_channel(np, rp); + if (err) + return err; + } + + return 0; +} + +static int niu_set_ip_frag_rule(struct niu *np) +{ + struct niu_parent *parent = np->parent; + struct niu_classifier *cp = &np->clas; + struct niu_tcam_entry *tp; + int index, err; + + /* XXX fix this allocation scheme XXX */ + index = cp->tcam_index; + tp = &parent->tcam[index]; + + /* Note that the noport bit is the same in both ipv4 and + * ipv6 format TCAM entries. + */ + memset(tp, 0, sizeof(*tp)); + tp->key[1] = TCAM_V4KEY1_NOPORT; + tp->key_mask[1] = TCAM_V4KEY1_NOPORT; + tp->assoc_data = (TCAM_ASSOCDATA_TRES_USE_OFFSET | + ((u64)0 << TCAM_ASSOCDATA_OFFSET_SHIFT)); + err = tcam_write(np, index, tp->key, tp->key_mask); + if (err) + return err; + err = tcam_assoc_write(np, index, tp->assoc_data); + if (err) + return err; + + return 0; +} + +static int niu_init_classifier_hw(struct niu *np) +{ + struct niu_parent *parent = np->parent; + struct niu_classifier *cp = &np->clas; + int i, err; + + nw64(H1POLY, cp->h1_init); + nw64(H2POLY, cp->h2_init); + + err = niu_init_hostinfo(np); + if (err) + return err; + + for (i = 0; i < ENET_VLAN_TBL_NUM_ENTRIES; i++) { + struct niu_vlan_rdc *vp = &cp->vlan_mappings[i]; + + vlan_tbl_write(np, i, np->port, + vp->vlan_pref, vp->rdc_num); + } + + for (i = 0; i < cp->num_alt_mac_mappings; i++) { + struct niu_altmac_rdc *ap = &cp->alt_mac_mappings[i]; + + err = niu_set_alt_mac_rdc_table(np, ap->alt_mac_num, + ap->rdc_num, ap->mac_pref); + if (err) + return err; + } + + for (i = CLASS_CODE_USER_PROG1; i <= CLASS_CODE_SCTP_IPV6; i++) { + int index = i - CLASS_CODE_USER_PROG1; + + err = niu_set_tcam_key(np, i, parent->tcam_key[index]); + if (err) + return err; + err = niu_set_flow_key(np, i, parent->flow_key[index]); + if (err) + return err; + } + + err = niu_set_ip_frag_rule(np); + if (err) + return err; + + tcam_enable(np, 1); + + return 0; +} + +static int niu_zcp_write(struct niu *np, int index, u64 *data) +{ + nw64(ZCP_RAM_DATA0, data[0]); + nw64(ZCP_RAM_DATA1, data[1]); + nw64(ZCP_RAM_DATA2, data[2]); + nw64(ZCP_RAM_DATA3, data[3]); + nw64(ZCP_RAM_DATA4, data[4]); + nw64(ZCP_RAM_BE, ZCP_RAM_BE_VAL); + nw64(ZCP_RAM_ACC, + (ZCP_RAM_ACC_WRITE | + (0 << ZCP_RAM_ACC_ZFCID_SHIFT) | + (ZCP_RAM_SEL_CFIFO(np->port) << ZCP_RAM_ACC_RAM_SEL_SHIFT))); + + return niu_wait_bits_clear(np, ZCP_RAM_ACC, ZCP_RAM_ACC_BUSY, + 1000, 100); +} + +static int niu_zcp_read(struct niu *np, int index, u64 *data) +{ + int err; + + err = niu_wait_bits_clear(np, ZCP_RAM_ACC, ZCP_RAM_ACC_BUSY, + 1000, 100); + if (err) { + dev_err(np->device, PFX "%s: ZCP read busy won't clear, " + "ZCP_RAM_ACC[%llx]\n", np->dev->name, + (unsigned long long) nr64(ZCP_RAM_ACC)); + return err; + } + + nw64(ZCP_RAM_ACC, + (ZCP_RAM_ACC_READ | + (0 << ZCP_RAM_ACC_ZFCID_SHIFT) | + (ZCP_RAM_SEL_CFIFO(np->port) << ZCP_RAM_ACC_RAM_SEL_SHIFT))); + + err = niu_wait_bits_clear(np, ZCP_RAM_ACC, ZCP_RAM_ACC_BUSY, + 1000, 100); + if (err) { + dev_err(np->device, PFX "%s: ZCP read busy2 won't clear, " + "ZCP_RAM_ACC[%llx]\n", np->dev->name, + (unsigned long long) nr64(ZCP_RAM_ACC)); + return err; + } + + data[0] = nr64(ZCP_RAM_DATA0); + data[1] = nr64(ZCP_RAM_DATA1); + data[2] = nr64(ZCP_RAM_DATA2); + data[3] = nr64(ZCP_RAM_DATA3); + data[4] = nr64(ZCP_RAM_DATA4); + + return 0; +} + +static void niu_zcp_cfifo_reset(struct niu *np) +{ + u64 val = nr64(RESET_CFIFO); + + val |= RESET_CFIFO_RST(np->port); + nw64(RESET_CFIFO, val); + udelay(10); + + val &= ~RESET_CFIFO_RST(np->port); + nw64(RESET_CFIFO, val); +} + +static int niu_init_zcp(struct niu *np) +{ + u64 data[5], rbuf[5]; + int i, max, err; + + if (np->parent->plat_type != PLAT_TYPE_NIU) { + if (np->port == 0 || np->port == 1) + max = ATLAS_P0_P1_CFIFO_ENTRIES; + else + max = ATLAS_P2_P3_CFIFO_ENTRIES; + } else + max = NIU_CFIFO_ENTRIES; + + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + + for (i = 0; i < max; i++) { + err = niu_zcp_write(np, i, data); + if (err) + return err; + err = niu_zcp_read(np, i, rbuf); + if (err) + return err; + } + + niu_zcp_cfifo_reset(np); + nw64(CFIFO_ECC(np->port), 0); + nw64(ZCP_INT_STAT, ZCP_INT_STAT_ALL); + (void) nr64(ZCP_INT_STAT); + nw64(ZCP_INT_MASK, ZCP_INT_MASK_ALL); + + return 0; +} + +static void niu_ipp_write(struct niu *np, int index, u64 *data) +{ + u64 val = nr64_ipp(IPP_CFIG); + + nw64_ipp(IPP_CFIG, val | IPP_CFIG_DFIFO_PIO_W); + nw64_ipp(IPP_DFIFO_WR_PTR, index); + nw64_ipp(IPP_DFIFO_WR0, data[0]); + nw64_ipp(IPP_DFIFO_WR1, data[1]); + nw64_ipp(IPP_DFIFO_WR2, data[2]); + nw64_ipp(IPP_DFIFO_WR3, data[3]); + nw64_ipp(IPP_DFIFO_WR4, data[4]); + nw64_ipp(IPP_CFIG, val & ~IPP_CFIG_DFIFO_PIO_W); +} + +static void niu_ipp_read(struct niu *np, int index, u64 *data) +{ + nw64_ipp(IPP_DFIFO_RD_PTR, index); + data[0] = nr64_ipp(IPP_DFIFO_RD0); + data[1] = nr64_ipp(IPP_DFIFO_RD1); + data[2] = nr64_ipp(IPP_DFIFO_RD2); + data[3] = nr64_ipp(IPP_DFIFO_RD3); + data[4] = nr64_ipp(IPP_DFIFO_RD4); +} + +static int niu_ipp_reset(struct niu *np) +{ + return niu_set_and_wait_clear_ipp(np, IPP_CFIG, IPP_CFIG_SOFT_RST, + 1000, 100, "IPP_CFIG"); +} + +static int niu_init_ipp(struct niu *np) +{ + u64 data[5], rbuf[5], val; + int i, max, err; + + if (np->parent->plat_type != PLAT_TYPE_NIU) { + if (np->port == 0 || np->port == 1) + max = ATLAS_P0_P1_DFIFO_ENTRIES; + else + max = ATLAS_P2_P3_DFIFO_ENTRIES; + } else + max = NIU_DFIFO_ENTRIES; + + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + + for (i = 0; i < max; i++) { + niu_ipp_write(np, i, data); + niu_ipp_read(np, i, rbuf); + } + + (void) nr64_ipp(IPP_INT_STAT); + (void) nr64_ipp(IPP_INT_STAT); + + err = niu_ipp_reset(np); + if (err) + return err; + + (void) nr64_ipp(IPP_PKT_DIS); + (void) nr64_ipp(IPP_BAD_CS_CNT); + (void) nr64_ipp(IPP_ECC); + + (void) nr64_ipp(IPP_INT_STAT); + + nw64_ipp(IPP_MSK, ~IPP_MSK_ALL); + + val = nr64_ipp(IPP_CFIG); + val &= ~IPP_CFIG_IP_MAX_PKT; + val |= (IPP_CFIG_IPP_ENABLE | + IPP_CFIG_DFIFO_ECC_EN | + IPP_CFIG_DROP_BAD_CRC | + IPP_CFIG_CKSUM_EN | + (0x1ffff << IPP_CFIG_IP_MAX_PKT_SHIFT)); + nw64_ipp(IPP_CFIG, val); + + return 0; +} + +static void niu_handle_led(struct niu *np, int status) +{ + u64 val; + val = nr64_mac(XMAC_CONFIG); + + if ((np->flags & NIU_FLAGS_10G) != 0 && + (np->flags & NIU_FLAGS_FIBER) != 0) { + if (status) { + val |= XMAC_CONFIG_LED_POLARITY; + val &= ~XMAC_CONFIG_FORCE_LED_ON; + } else { + val |= XMAC_CONFIG_FORCE_LED_ON; + val &= ~XMAC_CONFIG_LED_POLARITY; + } + } + + nw64_mac(XMAC_CONFIG, val); +} + +static void niu_init_xif_xmac(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u64 val; + + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC; + + val |= XMAC_CONFIG_TX_OUTPUT_EN; + + if (lp->loopback_mode == LOOPBACK_MAC) { + val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC; + val |= XMAC_CONFIG_LOOPBACK; + } else { + val &= ~XMAC_CONFIG_LOOPBACK; + } + + if (np->flags & NIU_FLAGS_10G) { + val &= ~XMAC_CONFIG_LFS_DISABLE; + } else { + val |= XMAC_CONFIG_LFS_DISABLE; + if (!(np->flags & NIU_FLAGS_FIBER)) + val |= XMAC_CONFIG_1G_PCS_BYPASS; + else + val &= ~XMAC_CONFIG_1G_PCS_BYPASS; + } + + val &= ~XMAC_CONFIG_10G_XPCS_BYPASS; + + if (lp->active_speed == SPEED_100) + val |= XMAC_CONFIG_SEL_CLK_25MHZ; + else + val &= ~XMAC_CONFIG_SEL_CLK_25MHZ; + + nw64_mac(XMAC_CONFIG, val); + + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_MODE_MASK; + if (np->flags & NIU_FLAGS_10G) { + val |= XMAC_CONFIG_MODE_XGMII; + } else { + if (lp->active_speed == SPEED_100) + val |= XMAC_CONFIG_MODE_MII; + else + val |= XMAC_CONFIG_MODE_GMII; + } + + nw64_mac(XMAC_CONFIG, val); +} + +static void niu_init_xif_bmac(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u64 val; + + val = BMAC_XIF_CONFIG_TX_OUTPUT_EN; + + if (lp->loopback_mode == LOOPBACK_MAC) + val |= BMAC_XIF_CONFIG_MII_LOOPBACK; + else + val &= ~BMAC_XIF_CONFIG_MII_LOOPBACK; + + if (lp->active_speed == SPEED_1000) + val |= BMAC_XIF_CONFIG_GMII_MODE; + else + val &= ~BMAC_XIF_CONFIG_GMII_MODE; + + val &= ~(BMAC_XIF_CONFIG_LINK_LED | + BMAC_XIF_CONFIG_LED_POLARITY); + + if (!(np->flags & NIU_FLAGS_10G) && + !(np->flags & NIU_FLAGS_FIBER) && + lp->active_speed == SPEED_100) + val |= BMAC_XIF_CONFIG_25MHZ_CLOCK; + else + val &= ~BMAC_XIF_CONFIG_25MHZ_CLOCK; + + nw64_mac(BMAC_XIF_CONFIG, val); +} + +static void niu_init_xif(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_init_xif_xmac(np); + else + niu_init_xif_bmac(np); +} + +static void niu_pcs_mii_reset(struct niu *np) +{ + u64 val = nr64_pcs(PCS_MII_CTL); + val |= PCS_MII_CTL_RST; + nw64_pcs(PCS_MII_CTL, val); +} + +static void niu_xpcs_reset(struct niu *np) +{ + u64 val = nr64_xpcs(XPCS_CONTROL1); + val |= XPCS_CONTROL1_RESET; + nw64_xpcs(XPCS_CONTROL1, val); +} + +static int niu_init_pcs(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + u64 val; + + switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { + case NIU_FLAGS_FIBER: + /* 1G fiber */ + nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE); + nw64_pcs(PCS_DPATH_MODE, 0); + niu_pcs_mii_reset(np); + break; + + case NIU_FLAGS_10G: + case NIU_FLAGS_10G | NIU_FLAGS_FIBER: + if (!(np->flags & NIU_FLAGS_XMAC)) + return -EINVAL; + + /* 10G copper or fiber */ + val = nr64_mac(XMAC_CONFIG); + val &= ~XMAC_CONFIG_10G_XPCS_BYPASS; + nw64_mac(XMAC_CONFIG, val); + + niu_xpcs_reset(np); + + val = nr64_xpcs(XPCS_CONTROL1); + if (lp->loopback_mode == LOOPBACK_PHY) + val |= XPCS_CONTROL1_LOOPBACK; + else + val &= ~XPCS_CONTROL1_LOOPBACK; + nw64_xpcs(XPCS_CONTROL1, val); + + nw64_xpcs(XPCS_DESKEW_ERR_CNT, 0); + (void) nr64_xpcs(XPCS_SYMERR_CNT01); + (void) nr64_xpcs(XPCS_SYMERR_CNT23); + break; + + case 0: + /* 1G copper */ + nw64_pcs(PCS_DPATH_MODE, PCS_DPATH_MODE_MII); + niu_pcs_mii_reset(np); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int niu_reset_tx_xmac(struct niu *np) +{ + return niu_set_and_wait_clear_mac(np, XTXMAC_SW_RST, + (XTXMAC_SW_RST_REG_RS | + XTXMAC_SW_RST_SOFT_RST), + 1000, 100, "XTXMAC_SW_RST"); +} + +static int niu_reset_tx_bmac(struct niu *np) +{ + int limit; + + nw64_mac(BTXMAC_SW_RST, BTXMAC_SW_RST_RESET); + limit = 1000; + while (--limit >= 0) { + if (!(nr64_mac(BTXMAC_SW_RST) & BTXMAC_SW_RST_RESET)) + break; + udelay(100); + } + if (limit < 0) { + dev_err(np->device, PFX "Port %u TX BMAC would not reset, " + "BTXMAC_SW_RST[%llx]\n", + np->port, + (unsigned long long) nr64_mac(BTXMAC_SW_RST)); + return -ENODEV; + } + + return 0; +} + +static int niu_reset_tx_mac(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + return niu_reset_tx_xmac(np); + else + return niu_reset_tx_bmac(np); +} + +static void niu_init_tx_xmac(struct niu *np, u64 min, u64 max) +{ + u64 val; + + val = nr64_mac(XMAC_MIN); + val &= ~(XMAC_MIN_TX_MIN_PKT_SIZE | + XMAC_MIN_RX_MIN_PKT_SIZE); + val |= (min << XMAC_MIN_RX_MIN_PKT_SIZE_SHFT); + val |= (min << XMAC_MIN_TX_MIN_PKT_SIZE_SHFT); + nw64_mac(XMAC_MIN, val); + + nw64_mac(XMAC_MAX, max); + + nw64_mac(XTXMAC_STAT_MSK, ~(u64)0); + + val = nr64_mac(XMAC_IPG); + if (np->flags & NIU_FLAGS_10G) { + val &= ~XMAC_IPG_IPG_XGMII; + val |= (IPG_12_15_XGMII << XMAC_IPG_IPG_XGMII_SHIFT); + } else { + val &= ~XMAC_IPG_IPG_MII_GMII; + val |= (IPG_12_MII_GMII << XMAC_IPG_IPG_MII_GMII_SHIFT); + } + nw64_mac(XMAC_IPG, val); + + val = nr64_mac(XMAC_CONFIG); + val &= ~(XMAC_CONFIG_ALWAYS_NO_CRC | + XMAC_CONFIG_STRETCH_MODE | + XMAC_CONFIG_VAR_MIN_IPG_EN | + XMAC_CONFIG_TX_ENABLE); + nw64_mac(XMAC_CONFIG, val); + + nw64_mac(TXMAC_FRM_CNT, 0); + nw64_mac(TXMAC_BYTE_CNT, 0); +} + +static void niu_init_tx_bmac(struct niu *np, u64 min, u64 max) +{ + u64 val; + + nw64_mac(BMAC_MIN_FRAME, min); + nw64_mac(BMAC_MAX_FRAME, max); + + nw64_mac(BTXMAC_STATUS_MASK, ~(u64)0); + nw64_mac(BMAC_CTRL_TYPE, 0x8808); + nw64_mac(BMAC_PREAMBLE_SIZE, 7); + + val = nr64_mac(BTXMAC_CONFIG); + val &= ~(BTXMAC_CONFIG_FCS_DISABLE | + BTXMAC_CONFIG_ENABLE); + nw64_mac(BTXMAC_CONFIG, val); +} + +static void niu_init_tx_mac(struct niu *np) +{ + u64 min, max; + + min = 64; + if (np->dev->mtu > ETH_DATA_LEN) + max = 9216; + else + max = 1522; + + /* The XMAC_MIN register only accepts values for TX min which + * have the low 3 bits cleared. + */ + BUILD_BUG_ON(min & 0x7); + + if (np->flags & NIU_FLAGS_XMAC) + niu_init_tx_xmac(np, min, max); + else + niu_init_tx_bmac(np, min, max); +} + +static int niu_reset_rx_xmac(struct niu *np) +{ + int limit; + + nw64_mac(XRXMAC_SW_RST, + XRXMAC_SW_RST_REG_RS | XRXMAC_SW_RST_SOFT_RST); + limit = 1000; + while (--limit >= 0) { + if (!(nr64_mac(XRXMAC_SW_RST) & (XRXMAC_SW_RST_REG_RS | + XRXMAC_SW_RST_SOFT_RST))) + break; + udelay(100); + } + if (limit < 0) { + dev_err(np->device, PFX "Port %u RX XMAC would not reset, " + "XRXMAC_SW_RST[%llx]\n", + np->port, + (unsigned long long) nr64_mac(XRXMAC_SW_RST)); + return -ENODEV; + } + + return 0; +} + +static int niu_reset_rx_bmac(struct niu *np) +{ + int limit; + + nw64_mac(BRXMAC_SW_RST, BRXMAC_SW_RST_RESET); + limit = 1000; + while (--limit >= 0) { + if (!(nr64_mac(BRXMAC_SW_RST) & BRXMAC_SW_RST_RESET)) + break; + udelay(100); + } + if (limit < 0) { + dev_err(np->device, PFX "Port %u RX BMAC would not reset, " + "BRXMAC_SW_RST[%llx]\n", + np->port, + (unsigned long long) nr64_mac(BRXMAC_SW_RST)); + return -ENODEV; + } + + return 0; +} + +static int niu_reset_rx_mac(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + return niu_reset_rx_xmac(np); + else + return niu_reset_rx_bmac(np); +} + +static void niu_init_rx_xmac(struct niu *np) +{ + struct niu_parent *parent = np->parent; + struct niu_rdc_tables *tp = &parent->rdc_group_cfg[np->port]; + int first_rdc_table = tp->first_table_num; + unsigned long i; + u64 val; + + nw64_mac(XMAC_ADD_FILT0, 0); + nw64_mac(XMAC_ADD_FILT1, 0); + nw64_mac(XMAC_ADD_FILT2, 0); + nw64_mac(XMAC_ADD_FILT12_MASK, 0); + nw64_mac(XMAC_ADD_FILT00_MASK, 0); + for (i = 0; i < MAC_NUM_HASH; i++) + nw64_mac(XMAC_HASH_TBL(i), 0); + nw64_mac(XRXMAC_STAT_MSK, ~(u64)0); + niu_set_primary_mac_rdc_table(np, first_rdc_table, 1); + niu_set_multicast_mac_rdc_table(np, first_rdc_table, 1); + + val = nr64_mac(XMAC_CONFIG); + val &= ~(XMAC_CONFIG_RX_MAC_ENABLE | + XMAC_CONFIG_PROMISCUOUS | + XMAC_CONFIG_PROMISC_GROUP | + XMAC_CONFIG_ERR_CHK_DIS | + XMAC_CONFIG_RX_CRC_CHK_DIS | + XMAC_CONFIG_RESERVED_MULTICAST | + XMAC_CONFIG_RX_CODEV_CHK_DIS | + XMAC_CONFIG_ADDR_FILTER_EN | + XMAC_CONFIG_RCV_PAUSE_ENABLE | + XMAC_CONFIG_STRIP_CRC | + XMAC_CONFIG_PASS_FLOW_CTRL | + XMAC_CONFIG_MAC2IPP_PKT_CNT_EN); + val |= (XMAC_CONFIG_HASH_FILTER_EN); + nw64_mac(XMAC_CONFIG, val); + + nw64_mac(RXMAC_BT_CNT, 0); + nw64_mac(RXMAC_BC_FRM_CNT, 0); + nw64_mac(RXMAC_MC_FRM_CNT, 0); + nw64_mac(RXMAC_FRAG_CNT, 0); + nw64_mac(RXMAC_HIST_CNT1, 0); + nw64_mac(RXMAC_HIST_CNT2, 0); + nw64_mac(RXMAC_HIST_CNT3, 0); + nw64_mac(RXMAC_HIST_CNT4, 0); + nw64_mac(RXMAC_HIST_CNT5, 0); + nw64_mac(RXMAC_HIST_CNT6, 0); + nw64_mac(RXMAC_HIST_CNT7, 0); + nw64_mac(RXMAC_MPSZER_CNT, 0); + nw64_mac(RXMAC_CRC_ER_CNT, 0); + nw64_mac(RXMAC_CD_VIO_CNT, 0); + nw64_mac(LINK_FAULT_CNT, 0); +} + +static void niu_init_rx_bmac(struct niu *np) +{ + struct niu_parent *parent = np->parent; + struct niu_rdc_tables *tp = &parent->rdc_group_cfg[np->port]; + int first_rdc_table = tp->first_table_num; + unsigned long i; + u64 val; + + nw64_mac(BMAC_ADD_FILT0, 0); + nw64_mac(BMAC_ADD_FILT1, 0); + nw64_mac(BMAC_ADD_FILT2, 0); + nw64_mac(BMAC_ADD_FILT12_MASK, 0); + nw64_mac(BMAC_ADD_FILT00_MASK, 0); + for (i = 0; i < MAC_NUM_HASH; i++) + nw64_mac(BMAC_HASH_TBL(i), 0); + niu_set_primary_mac_rdc_table(np, first_rdc_table, 1); + niu_set_multicast_mac_rdc_table(np, first_rdc_table, 1); + nw64_mac(BRXMAC_STATUS_MASK, ~(u64)0); + + val = nr64_mac(BRXMAC_CONFIG); + val &= ~(BRXMAC_CONFIG_ENABLE | + BRXMAC_CONFIG_STRIP_PAD | + BRXMAC_CONFIG_STRIP_FCS | + BRXMAC_CONFIG_PROMISC | + BRXMAC_CONFIG_PROMISC_GRP | + BRXMAC_CONFIG_ADDR_FILT_EN | + BRXMAC_CONFIG_DISCARD_DIS); + val |= (BRXMAC_CONFIG_HASH_FILT_EN); + nw64_mac(BRXMAC_CONFIG, val); + + val = nr64_mac(BMAC_ADDR_CMPEN); + val |= BMAC_ADDR_CMPEN_EN0; + nw64_mac(BMAC_ADDR_CMPEN, val); +} + +static void niu_init_rx_mac(struct niu *np) +{ + niu_set_primary_mac(np, np->dev->dev_addr); + + if (np->flags & NIU_FLAGS_XMAC) + niu_init_rx_xmac(np); + else + niu_init_rx_bmac(np); +} + +static void niu_enable_tx_xmac(struct niu *np, int on) +{ + u64 val = nr64_mac(XMAC_CONFIG); + + if (on) + val |= XMAC_CONFIG_TX_ENABLE; + else + val &= ~XMAC_CONFIG_TX_ENABLE; + nw64_mac(XMAC_CONFIG, val); +} + +static void niu_enable_tx_bmac(struct niu *np, int on) +{ + u64 val = nr64_mac(BTXMAC_CONFIG); + + if (on) + val |= BTXMAC_CONFIG_ENABLE; + else + val &= ~BTXMAC_CONFIG_ENABLE; + nw64_mac(BTXMAC_CONFIG, val); +} + +static void niu_enable_tx_mac(struct niu *np, int on) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_enable_tx_xmac(np, on); + else + niu_enable_tx_bmac(np, on); +} + +static void niu_enable_rx_xmac(struct niu *np, int on) +{ + u64 val = nr64_mac(XMAC_CONFIG); + + val &= ~(XMAC_CONFIG_HASH_FILTER_EN | + XMAC_CONFIG_PROMISCUOUS); + + if (np->flags & NIU_FLAGS_MCAST) + val |= XMAC_CONFIG_HASH_FILTER_EN; + if (np->flags & NIU_FLAGS_PROMISC) + val |= XMAC_CONFIG_PROMISCUOUS; + + if (on) + val |= XMAC_CONFIG_RX_MAC_ENABLE; + else + val &= ~XMAC_CONFIG_RX_MAC_ENABLE; + nw64_mac(XMAC_CONFIG, val); +} + +static void niu_enable_rx_bmac(struct niu *np, int on) +{ + u64 val = nr64_mac(BRXMAC_CONFIG); + + val &= ~(BRXMAC_CONFIG_HASH_FILT_EN | + BRXMAC_CONFIG_PROMISC); + + if (np->flags & NIU_FLAGS_MCAST) + val |= BRXMAC_CONFIG_HASH_FILT_EN; + if (np->flags & NIU_FLAGS_PROMISC) + val |= BRXMAC_CONFIG_PROMISC; + + if (on) + val |= BRXMAC_CONFIG_ENABLE; + else + val &= ~BRXMAC_CONFIG_ENABLE; + nw64_mac(BRXMAC_CONFIG, val); +} + +static void niu_enable_rx_mac(struct niu *np, int on) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_enable_rx_xmac(np, on); + else + niu_enable_rx_bmac(np, on); +} + +static int niu_init_mac(struct niu *np) +{ + int err; + + niu_init_xif(np); + err = niu_init_pcs(np); + if (err) + return err; + + err = niu_reset_tx_mac(np); + if (err) + return err; + niu_init_tx_mac(np); + err = niu_reset_rx_mac(np); + if (err) + return err; + niu_init_rx_mac(np); + + /* This looks hookey but the RX MAC reset we just did will + * undo some of the state we setup in niu_init_tx_mac() so we + * have to call it again. In particular, the RX MAC reset will + * set the XMAC_MAX register back to it's default value. + */ + niu_init_tx_mac(np); + niu_enable_tx_mac(np, 1); + + niu_enable_rx_mac(np, 1); + + return 0; +} + +static void niu_stop_one_tx_channel(struct niu *np, struct tx_ring_info *rp) +{ + (void) niu_tx_channel_stop(np, rp->tx_channel); +} + +static void niu_stop_tx_channels(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + niu_stop_one_tx_channel(np, rp); + } +} + +static void niu_reset_one_tx_channel(struct niu *np, struct tx_ring_info *rp) +{ + (void) niu_tx_channel_reset(np, rp->tx_channel); +} + +static void niu_reset_tx_channels(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + niu_reset_one_tx_channel(np, rp); + } +} + +static void niu_stop_one_rx_channel(struct niu *np, struct rx_ring_info *rp) +{ + (void) niu_enable_rx_channel(np, rp->rx_channel, 0); +} + +static void niu_stop_rx_channels(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + niu_stop_one_rx_channel(np, rp); + } +} + +static void niu_reset_one_rx_channel(struct niu *np, struct rx_ring_info *rp) +{ + int channel = rp->rx_channel; + + (void) niu_rx_channel_reset(np, channel); + nw64(RX_DMA_ENT_MSK(channel), RX_DMA_ENT_MSK_ALL); + nw64(RX_DMA_CTL_STAT(channel), 0); + (void) niu_enable_rx_channel(np, channel, 0); +} + +static void niu_reset_rx_channels(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + niu_reset_one_rx_channel(np, rp); + } +} + +static void niu_disable_ipp(struct niu *np) +{ + u64 rd, wr, val; + int limit; + + rd = nr64_ipp(IPP_DFIFO_RD_PTR); + wr = nr64_ipp(IPP_DFIFO_WR_PTR); + limit = 100; + while (--limit >= 0 && (rd != wr)) { + rd = nr64_ipp(IPP_DFIFO_RD_PTR); + wr = nr64_ipp(IPP_DFIFO_WR_PTR); + } + if (limit < 0 && + (rd != 0 && wr != 1)) { + dev_err(np->device, PFX "%s: IPP would not quiesce, " + "rd_ptr[%llx] wr_ptr[%llx]\n", + np->dev->name, + (unsigned long long) nr64_ipp(IPP_DFIFO_RD_PTR), + (unsigned long long) nr64_ipp(IPP_DFIFO_WR_PTR)); + } + + val = nr64_ipp(IPP_CFIG); + val &= ~(IPP_CFIG_IPP_ENABLE | + IPP_CFIG_DFIFO_ECC_EN | + IPP_CFIG_DROP_BAD_CRC | + IPP_CFIG_CKSUM_EN); + nw64_ipp(IPP_CFIG, val); + + (void) niu_ipp_reset(np); +} + +static int niu_init_hw(struct niu *np) +{ + int i, err; + + niudbg(IFUP, "%s: Initialize TXC\n", np->dev->name); + niu_txc_enable_port(np, 1); + niu_txc_port_dma_enable(np, 1); + niu_txc_set_imask(np, 0); + + niudbg(IFUP, "%s: Initialize TX channels\n", np->dev->name); + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + err = niu_init_one_tx_channel(np, rp); + if (err) + return err; + } + + niudbg(IFUP, "%s: Initialize RX channels\n", np->dev->name); + err = niu_init_rx_channels(np); + if (err) + goto out_uninit_tx_channels; + + niudbg(IFUP, "%s: Initialize classifier\n", np->dev->name); + err = niu_init_classifier_hw(np); + if (err) + goto out_uninit_rx_channels; + + niudbg(IFUP, "%s: Initialize ZCP\n", np->dev->name); + err = niu_init_zcp(np); + if (err) + goto out_uninit_rx_channels; + + niudbg(IFUP, "%s: Initialize IPP\n", np->dev->name); + err = niu_init_ipp(np); + if (err) + goto out_uninit_rx_channels; + + niudbg(IFUP, "%s: Initialize MAC\n", np->dev->name); + err = niu_init_mac(np); + if (err) + goto out_uninit_ipp; + + return 0; + +out_uninit_ipp: + niudbg(IFUP, "%s: Uninit IPP\n", np->dev->name); + niu_disable_ipp(np); + +out_uninit_rx_channels: + niudbg(IFUP, "%s: Uninit RX channels\n", np->dev->name); + niu_stop_rx_channels(np); + niu_reset_rx_channels(np); + +out_uninit_tx_channels: + niudbg(IFUP, "%s: Uninit TX channels\n", np->dev->name); + niu_stop_tx_channels(np); + niu_reset_tx_channels(np); + + return err; +} + +static void niu_stop_hw(struct niu *np) +{ + niudbg(IFDOWN, "%s: Disable interrupts\n", np->dev->name); + niu_enable_interrupts(np, 0); + + niudbg(IFDOWN, "%s: Disable RX MAC\n", np->dev->name); + niu_enable_rx_mac(np, 0); + + niudbg(IFDOWN, "%s: Disable IPP\n", np->dev->name); + niu_disable_ipp(np); + + niudbg(IFDOWN, "%s: Stop TX channels\n", np->dev->name); + niu_stop_tx_channels(np); + + niudbg(IFDOWN, "%s: Stop RX channels\n", np->dev->name); + niu_stop_rx_channels(np); + + niudbg(IFDOWN, "%s: Reset TX channels\n", np->dev->name); + niu_reset_tx_channels(np); + + niudbg(IFDOWN, "%s: Reset RX channels\n", np->dev->name); + niu_reset_rx_channels(np); +} + +static int niu_request_irq(struct niu *np) +{ + int i, j, err; + + err = 0; + for (i = 0; i < np->num_ldg; i++) { + struct niu_ldg *lp = &np->ldg[i]; + + err = request_irq(lp->irq, niu_interrupt, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, + np->dev->name, lp); + if (err) + goto out_free_irqs; + + } + + return 0; + +out_free_irqs: + for (j = 0; j < i; j++) { + struct niu_ldg *lp = &np->ldg[j]; + + free_irq(lp->irq, lp); + } + return err; +} + +static void niu_free_irq(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_ldg; i++) { + struct niu_ldg *lp = &np->ldg[i]; + + free_irq(lp->irq, lp); + } +} + +static void niu_enable_napi(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_ldg; i++) { +#ifdef NIU_NAPI_STRUCT + napi_enable(&np->ldg[i].napi); +#else + netif_poll_enable(np->ldg[i].dummy_netdev); +#endif + } +} + +static void niu_disable_napi(struct niu *np) +{ + int i; + + for (i = 0; i < np->num_ldg; i++) { +#ifdef NIU_NAPI_STRUCT + napi_disable(&np->ldg[i].napi); +#else + netif_poll_disable(np->ldg[i].dummy_netdev); +#endif + } +} + +static int niu_open(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + int err; + + netif_carrier_off(dev); + + err = niu_alloc_channels(np); + if (err) + goto out_err; + + err = niu_enable_interrupts(np, 0); + if (err) + goto out_free_channels; + + err = niu_request_irq(np); + if (err) + goto out_free_channels; + + niu_enable_napi(np); + + spin_lock_irq(&np->lock); + + err = niu_init_hw(np); + if (!err) { + init_timer(&np->timer); + np->timer.expires = jiffies + HZ; + np->timer.data = (unsigned long) np; + np->timer.function = niu_timer; + + err = niu_enable_interrupts(np, 1); + if (err) + niu_stop_hw(np); + } + + spin_unlock_irq(&np->lock); + + if (err) { + niu_disable_napi(np); + goto out_free_irq; + } + + netif_start_queue(dev); + + if (np->link_config.loopback_mode != LOOPBACK_DISABLED) + netif_carrier_on(dev); + + add_timer(&np->timer); + + return 0; + +out_free_irq: + niu_free_irq(np); + +out_free_channels: + niu_free_channels(np); + +out_err: + return err; +} + +static void niu_full_shutdown(struct niu *np, struct net_device *dev) +{ + cancel_work_sync(&np->reset_task); + + niu_disable_napi(np); + netif_stop_queue(dev); + + del_timer_sync(&np->timer); + + spin_lock_irq(&np->lock); + + niu_stop_hw(np); + + spin_unlock_irq(&np->lock); +} + +static int niu_close(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + niu_full_shutdown(np, dev); + + niu_free_irq(np); + + niu_free_channels(np); + + niu_handle_led(np, 0); + + return 0; +} + +static void niu_sync_xmac_stats(struct niu *np) +{ + struct niu_xmac_stats *mp = &np->mac_stats.xmac; + + mp->tx_frames += nr64_mac(TXMAC_FRM_CNT); + mp->tx_bytes += nr64_mac(TXMAC_BYTE_CNT); + + mp->rx_link_faults += nr64_mac(LINK_FAULT_CNT); + mp->rx_align_errors += nr64_mac(RXMAC_ALIGN_ERR_CNT); + mp->rx_frags += nr64_mac(RXMAC_FRAG_CNT); + mp->rx_mcasts += nr64_mac(RXMAC_MC_FRM_CNT); + mp->rx_bcasts += nr64_mac(RXMAC_BC_FRM_CNT); + mp->rx_hist_cnt1 += nr64_mac(RXMAC_HIST_CNT1); + mp->rx_hist_cnt2 += nr64_mac(RXMAC_HIST_CNT2); + mp->rx_hist_cnt3 += nr64_mac(RXMAC_HIST_CNT3); + mp->rx_hist_cnt4 += nr64_mac(RXMAC_HIST_CNT4); + mp->rx_hist_cnt5 += nr64_mac(RXMAC_HIST_CNT5); + mp->rx_hist_cnt6 += nr64_mac(RXMAC_HIST_CNT6); + mp->rx_hist_cnt7 += nr64_mac(RXMAC_HIST_CNT7); + mp->rx_octets += nr64_mac(RXMAC_BT_CNT); + mp->rx_code_violations += nr64_mac(RXMAC_CD_VIO_CNT); + mp->rx_len_errors += nr64_mac(RXMAC_MPSZER_CNT); + mp->rx_crc_errors += nr64_mac(RXMAC_CRC_ER_CNT); +} + +static void niu_sync_bmac_stats(struct niu *np) +{ + struct niu_bmac_stats *mp = &np->mac_stats.bmac; + + mp->tx_bytes += nr64_mac(BTXMAC_BYTE_CNT); + mp->tx_frames += nr64_mac(BTXMAC_FRM_CNT); + + mp->rx_frames += nr64_mac(BRXMAC_FRAME_CNT); + mp->rx_align_errors += nr64_mac(BRXMAC_ALIGN_ERR_CNT); + mp->rx_crc_errors += nr64_mac(BRXMAC_ALIGN_ERR_CNT); + mp->rx_len_errors += nr64_mac(BRXMAC_CODE_VIOL_ERR_CNT); +} + +static void niu_sync_mac_stats(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_sync_xmac_stats(np); + else + niu_sync_bmac_stats(np); +} + +static void niu_get_rx_stats(struct niu *np) +{ + unsigned long pkts, dropped, errors, bytes; + int i; + + pkts = dropped = errors = bytes = 0; + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + pkts += rp->rx_packets; + bytes += rp->rx_bytes; + dropped += rp->rx_dropped; + errors += rp->rx_errors; + } + np->net_stats.rx_packets = pkts; + np->net_stats.rx_bytes = bytes; + np->net_stats.rx_dropped = dropped; + np->net_stats.rx_errors = errors; +} + +static void niu_get_tx_stats(struct niu *np) +{ + unsigned long pkts, errors, bytes; + int i; + + pkts = errors = bytes = 0; + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + pkts += rp->tx_packets; + bytes += rp->tx_bytes; + errors += rp->tx_errors; + } + np->net_stats.tx_packets = pkts; + np->net_stats.tx_bytes = bytes; + np->net_stats.tx_errors = errors; +} + +static struct net_device_stats *niu_get_stats(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + niu_get_rx_stats(np); + niu_get_tx_stats(np); + + return &np->net_stats; +} + +static void niu_load_hash_xmac(struct niu *np, u16 *hash) +{ + int i; + + for (i = 0; i < 16; i++) + nw64_mac(XMAC_HASH_TBL(i), hash[i]); +} + +static void niu_load_hash_bmac(struct niu *np, u16 *hash) +{ + int i; + + for (i = 0; i < 16; i++) + nw64_mac(BMAC_HASH_TBL(i), hash[i]); +} + +static void niu_load_hash(struct niu *np, u16 *hash) +{ + if (np->flags & NIU_FLAGS_XMAC) + niu_load_hash_xmac(np, hash); + else + niu_load_hash_bmac(np, hash); +} + +static void niu_set_rx_mode(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + int i, err; + struct dev_mc_list *addr; + unsigned long flags; + u16 hash[16] = { 0, }; + + spin_lock_irqsave(&np->lock, flags); + niu_enable_rx_mac(np, 0); + + np->flags &= ~(NIU_FLAGS_MCAST | NIU_FLAGS_PROMISC); + if (dev->flags & IFF_PROMISC) + np->flags |= NIU_FLAGS_PROMISC; + if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0)) + np->flags |= NIU_FLAGS_MCAST; + + for (i = 0; i < niu_num_alt_addr(np); i++) { + err = niu_enable_alt_mac(np, i, 0); + if (err) + printk(KERN_WARNING PFX "%s: Error %d " + "disabling alt mac %d\n", + dev->name, err, i); + } + + if (dev->flags & IFF_ALLMULTI) { + for (i = 0; i < 16; i++) + hash[i] = 0xffff; + } else if (dev->mc_count > 0) { + for (addr = dev->mc_list; addr; addr = addr->next) { + u32 crc = ether_crc_le(ETH_ALEN, addr->dmi_addr); + + crc >>= 24; + hash[crc >> 4] |= (1 << (15 - (crc & 0xf))); + } + } + + if (np->flags & NIU_FLAGS_MCAST) + niu_load_hash(np, hash); + + niu_enable_rx_mac(np, 1); + spin_unlock_irqrestore(&np->lock, flags); +} + +static int niu_set_mac_addr(struct net_device *dev, void *p) +{ + struct niu *np = netdev_priv(dev); + struct sockaddr *addr = p; + unsigned long flags; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + + if (!netif_running(dev)) + return 0; + + spin_lock_irqsave(&np->lock, flags); + niu_enable_rx_mac(np, 0); + niu_set_primary_mac(np, dev->dev_addr); + niu_enable_rx_mac(np, 1); + spin_unlock_irqrestore(&np->lock, flags); + + return 0; +} + +static int niu_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + return -EOPNOTSUPP; +} + +static void niu_netif_stop(struct niu *np) +{ + np->dev->trans_start = jiffies; /* prevent tx timeout */ + + niu_disable_napi(np); + + netif_tx_disable(np->dev); +} + +static void niu_netif_start(struct niu *np) +{ + /* NOTE: unconditional netif_wake_queue is only appropriate + * so long as all callers are assured to have free tx slots + * (such as after niu_init_hw). + */ + netif_wake_queue(np->dev); + + niu_enable_napi(np); + + niu_enable_interrupts(np, 1); +} + +static void niu_reset_task(struct work_struct *work) +{ + struct niu *np = container_of(work, struct niu, reset_task); + unsigned long flags; + int err; + + spin_lock_irqsave(&np->lock, flags); + if (!netif_running(np->dev)) { + spin_unlock_irqrestore(&np->lock, flags); + return; + } + + spin_unlock_irqrestore(&np->lock, flags); + + del_timer_sync(&np->timer); + + niu_netif_stop(np); + + spin_lock_irqsave(&np->lock, flags); + + niu_stop_hw(np); + + err = niu_init_hw(np); + if (!err) { + np->timer.expires = jiffies + HZ; + add_timer(&np->timer); + niu_netif_start(np); + } + + spin_unlock_irqrestore(&np->lock, flags); +} + +static void niu_tx_timeout(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + dev_err(np->device, PFX "%s: Transmit timed out, resetting\n", + dev->name); + + schedule_work(&np->reset_task); +} + +static void niu_set_txd(struct tx_ring_info *rp, int index, + u64 mapping, u64 len, u64 mark, + u64 n_frags) +{ + __le64 *desc = &rp->descr[index]; + + *desc = cpu_to_le64(mark | + (n_frags << TX_DESC_NUM_PTR_SHIFT) | + (len << TX_DESC_TR_LEN_SHIFT) | + (mapping & TX_DESC_SAD)); +} + +static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr, + u64 pad_bytes, u64 len) +{ + u16 eth_proto, eth_proto_inner; + u64 csum_bits, l3off, ihl, ret; + u8 ip_proto; + int ipv6; + + eth_proto = be16_to_cpu(ehdr->h_proto); + eth_proto_inner = eth_proto; + if (eth_proto == ETH_P_8021Q) { + struct vlan_ethhdr *vp = (struct vlan_ethhdr *) ehdr; + __be16 val = vp->h_vlan_encapsulated_proto; + + eth_proto_inner = be16_to_cpu(val); + } + + ipv6 = ihl = 0; + switch (skb->protocol) { + case __constant_htons(ETH_P_IP): + ip_proto = ip_hdr(skb)->protocol; + ihl = ip_hdr(skb)->ihl; + break; + case __constant_htons(ETH_P_IPV6): + ip_proto = ipv6_hdr(skb)->nexthdr; + ihl = (40 >> 2); + ipv6 = 1; + break; + default: + ip_proto = ihl = 0; + break; + } + + csum_bits = TXHDR_CSUM_NONE; + if (skb->ip_summed == CHECKSUM_PARTIAL) { + u64 start, stuff; + + csum_bits = (ip_proto == IPPROTO_TCP ? + TXHDR_CSUM_TCP : + (ip_proto == IPPROTO_UDP ? + TXHDR_CSUM_UDP : TXHDR_CSUM_SCTP)); + + start = skb_transport_offset(skb) - + (pad_bytes + sizeof(struct tx_pkt_hdr)); + stuff = start + skb->csum_offset; + + csum_bits |= (start / 2) << TXHDR_L4START_SHIFT; + csum_bits |= (stuff / 2) << TXHDR_L4STUFF_SHIFT; + } + + l3off = skb_network_offset(skb) - + (pad_bytes + sizeof(struct tx_pkt_hdr)); + + ret = (((pad_bytes / 2) << TXHDR_PAD_SHIFT) | + (len << TXHDR_LEN_SHIFT) | + ((l3off / 2) << TXHDR_L3START_SHIFT) | + (ihl << TXHDR_IHL_SHIFT) | + ((eth_proto_inner < 1536) ? TXHDR_LLC : 0) | + ((eth_proto == ETH_P_8021Q) ? TXHDR_VLAN : 0) | + (ipv6 ? TXHDR_IP_VER : 0) | + csum_bits); + + return ret; +} + +static struct tx_ring_info *tx_ring_select(struct niu *np, struct sk_buff *skb) +{ + return &np->tx_rings[0]; +} + +static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + unsigned long align, headroom; + struct tx_ring_info *rp; + struct tx_pkt_hdr *tp; + unsigned int len, nfg; + struct ethhdr *ehdr; + int prod, i, tlen; + u64 mapping, mrk; + + rp = tx_ring_select(np, skb); + + if (niu_tx_avail(rp) <= (skb_shinfo(skb)->nr_frags + 1)) { + netif_stop_queue(dev); + dev_err(np->device, PFX "%s: BUG! Tx ring full when " + "queue awake!\n", dev->name); + rp->tx_errors++; + return NETDEV_TX_BUSY; + } + + if (skb->len < ETH_ZLEN) { + unsigned int pad_bytes = ETH_ZLEN - skb->len; + + if (skb_pad(skb, pad_bytes)) + goto out; + skb_put(skb, pad_bytes); + } + + len = sizeof(struct tx_pkt_hdr) + 15; + if (skb_headroom(skb) < len) { + struct sk_buff *skb_new; + + skb_new = skb_realloc_headroom(skb, len); + if (!skb_new) { + rp->tx_errors++; + goto out_drop; + } + kfree_skb(skb); + skb = skb_new; + } + + align = ((unsigned long) skb->data & (16 - 1)); + headroom = align + sizeof(struct tx_pkt_hdr); + + ehdr = (struct ethhdr *) skb->data; + tp = (struct tx_pkt_hdr *) skb_push(skb, headroom); + + len = skb->len - sizeof(struct tx_pkt_hdr); + tp->flags = cpu_to_le64(niu_compute_tx_flags(skb, ehdr, align, len)); + tp->resv = 0; + + len = skb_headlen(skb); + mapping = np->ops->map_single(np->device, skb->data, + len, DMA_TO_DEVICE); + + prod = rp->prod; + + rp->tx_buffs[prod].skb = skb; + rp->tx_buffs[prod].mapping = mapping; + + mrk = TX_DESC_SOP; + if (++rp->mark_counter == rp->mark_freq) { + rp->mark_counter = 0; + mrk |= TX_DESC_MARK; + rp->mark_pending++; + } + + tlen = len; + nfg = skb_shinfo(skb)->nr_frags; + while (tlen > 0) { + tlen -= MAX_TX_DESC_LEN; + nfg++; + } + + while (len > 0) { + unsigned int this_len = len; + + if (this_len > MAX_TX_DESC_LEN) + this_len = MAX_TX_DESC_LEN; + + niu_set_txd(rp, prod, mapping, this_len, mrk, nfg); + mrk = nfg = 0; + + prod = NEXT_TX(rp, prod); + mapping += this_len; + len -= this_len; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + len = frag->size; + mapping = np->ops->map_page(np->device, frag->page, + frag->page_offset, len, + DMA_TO_DEVICE); + + rp->tx_buffs[prod].skb = NULL; + rp->tx_buffs[prod].mapping = mapping; + + niu_set_txd(rp, prod, mapping, len, 0, 0); + + prod = NEXT_TX(rp, prod); + } + + if (prod < rp->prod) + rp->wrap_bit ^= TX_RING_KICK_WRAP; + rp->prod = prod; + + nw64(TX_RING_KICK(rp->tx_channel), rp->wrap_bit | (prod << 3)); + + if (unlikely(niu_tx_avail(rp) <= (MAX_SKB_FRAGS + 1))) { + netif_stop_queue(dev); + if (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)) + netif_wake_queue(dev); + } + + dev->trans_start = jiffies; + +out: + return NETDEV_TX_OK; + +out_drop: + rp->tx_errors++; + kfree_skb(skb); + goto out; +} + +static int niu_change_mtu(struct net_device *dev, int new_mtu) +{ + struct niu *np = netdev_priv(dev); + int err, orig_jumbo, new_jumbo; + + if (new_mtu < 68 || new_mtu > NIU_MAX_MTU) + return -EINVAL; + + orig_jumbo = (dev->mtu > ETH_DATA_LEN); + new_jumbo = (new_mtu > ETH_DATA_LEN); + + dev->mtu = new_mtu; + + if (!netif_running(dev) || + (orig_jumbo == new_jumbo)) + return 0; + + niu_full_shutdown(np, dev); + + niu_free_channels(np); + + niu_enable_napi(np); + + err = niu_alloc_channels(np); + if (err) + return err; + + spin_lock_irq(&np->lock); + + err = niu_init_hw(np); + if (!err) { + init_timer(&np->timer); + np->timer.expires = jiffies + HZ; + np->timer.data = (unsigned long) np; + np->timer.function = niu_timer; + + err = niu_enable_interrupts(np, 1); + if (err) + niu_stop_hw(np); + } + + spin_unlock_irq(&np->lock); + + if (!err) { + netif_start_queue(dev); + if (np->link_config.loopback_mode != LOOPBACK_DISABLED) + netif_carrier_on(dev); + + add_timer(&np->timer); + } + + return err; +} + +static void niu_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct niu *np = netdev_priv(dev); + struct niu_vpd *vpd = &np->vpd; + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + sprintf(info->fw_version, "%d.%d", + vpd->fcode_major, vpd->fcode_minor); + if (np->parent->plat_type != PLAT_TYPE_NIU) + strcpy(info->bus_info, pci_name(np->pdev)); +} + +static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct niu *np = netdev_priv(dev); + struct niu_link_config *lp; + + lp = &np->link_config; + + memset(cmd, 0, sizeof(*cmd)); + cmd->phy_address = np->phy_addr; + cmd->supported = lp->supported; + cmd->advertising = lp->advertising; + cmd->autoneg = lp->autoneg; + cmd->speed = lp->active_speed; + cmd->duplex = lp->active_duplex; + + return 0; +} + +static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + return -EINVAL; +} + +static u32 niu_get_msglevel(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + return np->msg_enable; +} + +static void niu_set_msglevel(struct net_device *dev, u32 value) +{ + struct niu *np = netdev_priv(dev); + np->msg_enable = value; +} + +static int niu_get_eeprom_len(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + return np->eeprom_len; +} + +static int niu_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct niu *np = netdev_priv(dev); + u32 offset, len, val; + + offset = eeprom->offset; + len = eeprom->len; + + if (offset + len < offset) + return -EINVAL; + if (offset >= np->eeprom_len) + return -EINVAL; + if (offset + len > np->eeprom_len) + len = eeprom->len = np->eeprom_len - offset; + + if (offset & 3) { + u32 b_offset, b_count; + + b_offset = offset & 3; + b_count = 4 - b_offset; + if (b_count > len) + b_count = len; + + val = nr64(ESPC_NCR((offset - b_offset) / 4)); + memcpy(data, ((char *)&val) + b_offset, b_count); + data += b_count; + len -= b_count; + offset += b_count; + } + while (len >= 4) { + val = nr64(ESPC_NCR(offset / 4)); + memcpy(data, &val, 4); + data += 4; + len -= 4; + offset += 4; + } + if (len) { + val = nr64(ESPC_NCR(offset / 4)); + memcpy(data, &val, len); + } + return 0; +} + +static const struct { + const char string[ETH_GSTRING_LEN]; +} niu_xmac_stat_keys[] = { + { "tx_frames" }, + { "tx_bytes" }, + { "tx_fifo_errors" }, + { "tx_overflow_errors" }, + { "tx_max_pkt_size_errors" }, + { "tx_underflow_errors" }, + { "rx_local_faults" }, + { "rx_remote_faults" }, + { "rx_link_faults" }, + { "rx_align_errors" }, + { "rx_frags" }, + { "rx_mcasts" }, + { "rx_bcasts" }, + { "rx_hist_cnt1" }, + { "rx_hist_cnt2" }, + { "rx_hist_cnt3" }, + { "rx_hist_cnt4" }, + { "rx_hist_cnt5" }, + { "rx_hist_cnt6" }, + { "rx_hist_cnt7" }, + { "rx_octets" }, + { "rx_code_violations" }, + { "rx_len_errors" }, + { "rx_crc_errors" }, + { "rx_underflows" }, + { "rx_overflows" }, + { "pause_off_state" }, + { "pause_on_state" }, + { "pause_received" }, +}; + +#define NUM_XMAC_STAT_KEYS ARRAY_SIZE(niu_xmac_stat_keys) + +static const struct { + const char string[ETH_GSTRING_LEN]; +} niu_bmac_stat_keys[] = { + { "tx_underflow_errors" }, + { "tx_max_pkt_size_errors" }, + { "tx_bytes" }, + { "tx_frames" }, + { "rx_overflows" }, + { "rx_frames" }, + { "rx_align_errors" }, + { "rx_crc_errors" }, + { "rx_len_errors" }, + { "pause_off_state" }, + { "pause_on_state" }, + { "pause_received" }, +}; + +#define NUM_BMAC_STAT_KEYS ARRAY_SIZE(niu_bmac_stat_keys) + +static const struct { + const char string[ETH_GSTRING_LEN]; +} niu_rxchan_stat_keys[] = { + { "rx_channel" }, + { "rx_packets" }, + { "rx_bytes" }, + { "rx_dropped" }, + { "rx_errors" }, +}; + +#define NUM_RXCHAN_STAT_KEYS ARRAY_SIZE(niu_rxchan_stat_keys) + +static const struct { + const char string[ETH_GSTRING_LEN]; +} niu_txchan_stat_keys[] = { + { "tx_channel" }, + { "tx_packets" }, + { "tx_bytes" }, + { "tx_errors" }, +}; + +#define NUM_TXCHAN_STAT_KEYS ARRAY_SIZE(niu_txchan_stat_keys) + +static void niu_get_strings(struct net_device *dev, u32 stringset, u8 *data) +{ + struct niu *np = netdev_priv(dev); + int i; + + if (stringset != ETH_SS_STATS) + return; + + if (np->flags & NIU_FLAGS_XMAC) { + memcpy(data, niu_xmac_stat_keys, + sizeof(niu_xmac_stat_keys)); + data += sizeof(niu_xmac_stat_keys); + } else { + memcpy(data, niu_bmac_stat_keys, + sizeof(niu_bmac_stat_keys)); + data += sizeof(niu_bmac_stat_keys); + } + for (i = 0; i < np->num_rx_rings; i++) { + memcpy(data, niu_rxchan_stat_keys, + sizeof(niu_rxchan_stat_keys)); + data += sizeof(niu_rxchan_stat_keys); + } + for (i = 0; i < np->num_tx_rings; i++) { + memcpy(data, niu_txchan_stat_keys, + sizeof(niu_txchan_stat_keys)); + data += sizeof(niu_txchan_stat_keys); + } +} + +static int niu_get_stats_count(struct net_device *dev) +{ + struct niu *np = netdev_priv(dev); + + return ((np->flags & NIU_FLAGS_XMAC ? + NUM_XMAC_STAT_KEYS : + NUM_BMAC_STAT_KEYS) + + (np->num_rx_rings * NUM_RXCHAN_STAT_KEYS) + + (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS)); +} + +static void niu_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct niu *np = netdev_priv(dev); + int i; + + niu_sync_mac_stats(np); + if (np->flags & NIU_FLAGS_XMAC) { + memcpy(data, &np->mac_stats.xmac, + sizeof(struct niu_xmac_stats)); + data += (sizeof(struct niu_xmac_stats) / sizeof(u64)); + } else { + memcpy(data, &np->mac_stats.bmac, + sizeof(struct niu_bmac_stats)); + data += (sizeof(struct niu_bmac_stats) / sizeof(u64)); + } + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + data[0] = rp->rx_channel; + data[1] = rp->rx_packets; + data[2] = rp->rx_bytes; + data[3] = rp->rx_dropped; + data[4] = rp->rx_errors; + data += 5; + } + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + data[0] = rp->tx_channel; + data[1] = rp->tx_packets; + data[2] = rp->tx_bytes; + data[3] = rp->tx_errors; + data += 4; + } +} + +static u64 niu_led_state_save(struct niu *np) +{ + if (np->flags & NIU_FLAGS_XMAC) + return nr64_mac(XMAC_CONFIG); + else + return nr64_mac(BMAC_XIF_CONFIG); +} + +static void niu_led_state_restore(struct niu *np, u64 val) +{ + if (np->flags & NIU_FLAGS_XMAC) + nw64_mac(XMAC_CONFIG, val); + else + nw64_mac(BMAC_XIF_CONFIG, val); +} + +static void niu_force_led(struct niu *np, int on) +{ + u64 val, reg, bit; + + if (np->flags & NIU_FLAGS_XMAC) { + reg = XMAC_CONFIG; + bit = XMAC_CONFIG_FORCE_LED_ON; + } else { + reg = BMAC_XIF_CONFIG; + bit = BMAC_XIF_CONFIG_LINK_LED; + } + + val = nr64_mac(reg); + if (on) + val |= bit; + else + val &= ~bit; + nw64_mac(reg, val); +} + +static int niu_phys_id(struct net_device *dev, u32 data) +{ + struct niu *np = netdev_priv(dev); + u64 orig_led_state; + int i; + + if (!netif_running(dev)) + return -EAGAIN; + + if (data == 0) + data = 2; + + orig_led_state = niu_led_state_save(np); + for (i = 0; i < (data * 2); i++) { + int on = ((i % 2) == 0); + + niu_force_led(np, on); + + if (msleep_interruptible(500)) + break; + } + niu_led_state_restore(np, orig_led_state); + + return 0; +} + +static const struct ethtool_ops niu_ethtool_ops = { + .get_drvinfo = niu_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_msglevel = niu_get_msglevel, + .set_msglevel = niu_set_msglevel, + .get_eeprom_len = niu_get_eeprom_len, + .get_eeprom = niu_get_eeprom, + .get_settings = niu_get_settings, + .set_settings = niu_set_settings, + .get_strings = niu_get_strings, + .get_stats_count = niu_get_stats_count, + .get_ethtool_stats = niu_get_ethtool_stats, + .phys_id = niu_phys_id, +}; + +static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent, + int ldg, int ldn) +{ + if (ldg < NIU_LDG_MIN || ldg > NIU_LDG_MAX) + return -EINVAL; + if (ldn < 0 || ldn > LDN_MAX) + return -EINVAL; + + parent->ldg_map[ldn] = ldg; + + if (np->parent->plat_type == PLAT_TYPE_NIU) { + /* On N2 NIU, the ldn-->ldg assignments are setup and fixed by + * the firmware, and we're not supposed to change them. + * Validate the mapping, because if it's wrong we probably + * won't get any interrupts and that's painful to debug. + */ + if (nr64(LDG_NUM(ldn)) != ldg) { + dev_err(np->device, PFX "Port %u, mis-matched " + "LDG assignment " + "for ldn %d, should be %d is %llu\n", + np->port, ldn, ldg, + (unsigned long long) nr64(LDG_NUM(ldn))); + return -EINVAL; + } + } else + nw64(LDG_NUM(ldn), ldg); + + return 0; +} + +static int niu_set_ldg_timer_res(struct niu *np, int res) +{ + if (res < 0 || res > LDG_TIMER_RES_VAL) + return -EINVAL; + + + nw64(LDG_TIMER_RES, res); + + return 0; +} + +static int niu_set_ldg_sid(struct niu *np, int ldg, int func, int vector) +{ + if ((ldg < NIU_LDG_MIN || ldg > NIU_LDG_MAX) || + (func < 0 || func > 3) || + (vector < 0 || vector > 0x1f)) + return -EINVAL; + + nw64(SID(ldg), (func << SID_FUNC_SHIFT) | vector); + + return 0; +} + +static int __devinit niu_pci_eeprom_read(struct niu *np, u32 addr) +{ + u64 frame, frame_base = (ESPC_PIO_STAT_READ_START | + (addr << ESPC_PIO_STAT_ADDR_SHIFT)); + int limit; + + if (addr > (ESPC_PIO_STAT_ADDR >> ESPC_PIO_STAT_ADDR_SHIFT)) + return -EINVAL; + + frame = frame_base; + nw64(ESPC_PIO_STAT, frame); + limit = 64; + do { + udelay(5); + frame = nr64(ESPC_PIO_STAT); + if (frame & ESPC_PIO_STAT_READ_END) + break; + } while (limit--); + if (!(frame & ESPC_PIO_STAT_READ_END)) { + dev_err(np->device, PFX "EEPROM read timeout frame[%llx]\n", + (unsigned long long) frame); + return -ENODEV; + } + + frame = frame_base; + nw64(ESPC_PIO_STAT, frame); + limit = 64; + do { + udelay(5); + frame = nr64(ESPC_PIO_STAT); + if (frame & ESPC_PIO_STAT_READ_END) + break; + } while (limit--); + if (!(frame & ESPC_PIO_STAT_READ_END)) { + dev_err(np->device, PFX "EEPROM read timeout frame[%llx]\n", + (unsigned long long) frame); + return -ENODEV; + } + + frame = nr64(ESPC_PIO_STAT); + return (frame & ESPC_PIO_STAT_DATA) >> ESPC_PIO_STAT_DATA_SHIFT; +} + +static int __devinit niu_pci_eeprom_read16(struct niu *np, u32 off) +{ + int err = niu_pci_eeprom_read(np, off); + u16 val; + + if (err < 0) + return err; + val = (err << 8); + err = niu_pci_eeprom_read(np, off + 1); + if (err < 0) + return err; + val |= (err & 0xff); + + return val; +} + +static int __devinit niu_pci_eeprom_read16_swp(struct niu *np, u32 off) +{ + int err = niu_pci_eeprom_read(np, off); + u16 val; + + if (err < 0) + return err; + + val = (err & 0xff); + err = niu_pci_eeprom_read(np, off + 1); + if (err < 0) + return err; + + val |= (err & 0xff) << 8; + + return val; +} + +static int __devinit niu_pci_vpd_get_propname(struct niu *np, + u32 off, + char *namebuf, + int namebuf_len) +{ + int i; + + for (i = 0; i < namebuf_len; i++) { + int err = niu_pci_eeprom_read(np, off + i); + if (err < 0) + return err; + *namebuf++ = err; + if (!err) + break; + } + if (i >= namebuf_len) + return -EINVAL; + + return i + 1; +} + +static void __devinit niu_vpd_parse_version(struct niu *np) +{ + struct niu_vpd *vpd = &np->vpd; + int len = strlen(vpd->version) + 1; + const char *s = vpd->version; + int i; + + for (i = 0; i < len - 5; i++) { + if (!strncmp(s + i, "FCode ", 5)) + break; + } + if (i >= len - 5) + return; + + s += i + 5; + sscanf(s, "%d.%d", &vpd->fcode_major, &vpd->fcode_minor); + + niudbg(PROBE, "VPD_SCAN: FCODE major(%d) minor(%d)\n", + vpd->fcode_major, vpd->fcode_minor); + if (vpd->fcode_major > NIU_VPD_MIN_MAJOR || + (vpd->fcode_major == NIU_VPD_MIN_MAJOR && + vpd->fcode_minor >= NIU_VPD_MIN_MINOR)) + np->flags |= NIU_FLAGS_VPD_VALID; +} + +/* ESPC_PIO_EN_ENABLE must be set */ +static int __devinit niu_pci_vpd_scan_props(struct niu *np, + u32 start, u32 end) +{ + unsigned int found_mask = 0; +#define FOUND_MASK_MODEL 0x00000001 +#define FOUND_MASK_BMODEL 0x00000002 +#define FOUND_MASK_VERS 0x00000004 +#define FOUND_MASK_MAC 0x00000008 +#define FOUND_MASK_NMAC 0x00000010 +#define FOUND_MASK_PHY 0x00000020 +#define FOUND_MASK_ALL 0x0000003f + + niudbg(PROBE, "VPD_SCAN: start[%x] end[%x]\n", + start, end); + while (start < end) { + int len, err, instance, type, prop_len; + char namebuf[64]; + u8 *prop_buf; + int max_len; + + if (found_mask == FOUND_MASK_ALL) { + niu_vpd_parse_version(np); + return 1; + } + + err = niu_pci_eeprom_read(np, start + 2); + if (err < 0) + return err; + len = err; + start += 3; + + instance = niu_pci_eeprom_read(np, start); + type = niu_pci_eeprom_read(np, start + 3); + prop_len = niu_pci_eeprom_read(np, start + 4); + err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64); + if (err < 0) + return err; + + prop_buf = NULL; + max_len = 0; + if (!strcmp(namebuf, "model")) { + prop_buf = np->vpd.model; + max_len = NIU_VPD_MODEL_MAX; + found_mask |= FOUND_MASK_MODEL; + } else if (!strcmp(namebuf, "board-model")) { + prop_buf = np->vpd.board_model; + max_len = NIU_VPD_BD_MODEL_MAX; + found_mask |= FOUND_MASK_BMODEL; + } else if (!strcmp(namebuf, "version")) { + prop_buf = np->vpd.version; + max_len = NIU_VPD_VERSION_MAX; + found_mask |= FOUND_MASK_VERS; + } else if (!strcmp(namebuf, "local-mac-address")) { + prop_buf = np->vpd.local_mac; + max_len = ETH_ALEN; + found_mask |= FOUND_MASK_MAC; + } else if (!strcmp(namebuf, "num-mac-addresses")) { + prop_buf = &np->vpd.mac_num; + max_len = 1; + found_mask |= FOUND_MASK_NMAC; + } else if (!strcmp(namebuf, "phy-type")) { + prop_buf = np->vpd.phy_type; + max_len = NIU_VPD_PHY_TYPE_MAX; + found_mask |= FOUND_MASK_PHY; + } + + if (max_len && prop_len > max_len) { + dev_err(np->device, PFX "Property '%s' length (%d) is " + "too long.\n", namebuf, prop_len); + return -EINVAL; + } + + if (prop_buf) { + u32 off = start + 5 + err; + int i; + + niudbg(PROBE, "VPD_SCAN: Reading in property [%s] " + "len[%d]\n", namebuf, prop_len); + for (i = 0; i < prop_len; i++) + *prop_buf++ = niu_pci_eeprom_read(np, off + i); + } + + start += len; + } + + return 0; +} + +/* ESPC_PIO_EN_ENABLE must be set */ +static void __devinit niu_pci_vpd_fetch(struct niu *np, u32 start) +{ + u32 offset; + int err; + + err = niu_pci_eeprom_read16_swp(np, start + 1); + if (err < 0) + return; + + offset = err + 3; + + while (start + offset < ESPC_EEPROM_SIZE) { + u32 here = start + offset; + u32 end; + + err = niu_pci_eeprom_read(np, here); + if (err != 0x90) + return; + + err = niu_pci_eeprom_read16_swp(np, here + 1); + if (err < 0) + return; + + here = start + offset + 3; + end = start + offset + err; + + offset += err; + + err = niu_pci_vpd_scan_props(np, here, end); + if (err < 0 || err == 1) + return; + } +} + +/* ESPC_PIO_EN_ENABLE must be set */ +static u32 __devinit niu_pci_vpd_offset(struct niu *np) +{ + u32 start = 0, end = ESPC_EEPROM_SIZE, ret; + int err; + + while (start < end) { + ret = start; + + /* ROM header signature? */ + err = niu_pci_eeprom_read16(np, start + 0); + if (err != 0x55aa) + return 0; + + /* Apply offset to PCI data structure. */ + err = niu_pci_eeprom_read16(np, start + 23); + if (err < 0) + return 0; + start += err; + + /* Check for "PCIR" signature. */ + err = niu_pci_eeprom_read16(np, start + 0); + if (err != 0x5043) + return 0; + err = niu_pci_eeprom_read16(np, start + 2); + if (err != 0x4952) + return 0; + + /* Check for OBP image type. */ + err = niu_pci_eeprom_read(np, start + 20); + if (err < 0) + return 0; + if (err != 0x01) { + err = niu_pci_eeprom_read(np, ret + 2); + if (err < 0) + return 0; + + start = ret + (err * 512); + continue; + } + + err = niu_pci_eeprom_read16_swp(np, start + 8); + if (err < 0) + return err; + ret += err; + + err = niu_pci_eeprom_read(np, ret + 0); + if (err != 0x82) + return 0; + + return ret; + } + + return 0; +} + +static int __devinit niu_phy_type_prop_decode(struct niu *np, + const char *phy_prop) +{ + if (!strcmp(phy_prop, "mif")) { + /* 1G copper, MII */ + np->flags &= ~(NIU_FLAGS_FIBER | + NIU_FLAGS_10G); + np->mac_xcvr = MAC_XCVR_MII; + } else if (!strcmp(phy_prop, "xgf")) { + /* 10G fiber, XPCS */ + np->flags |= (NIU_FLAGS_10G | + NIU_FLAGS_FIBER); + np->mac_xcvr = MAC_XCVR_XPCS; + } else if (!strcmp(phy_prop, "pcs")) { + /* 1G fiber, PCS */ + np->flags &= ~NIU_FLAGS_10G; + np->flags |= NIU_FLAGS_FIBER; + np->mac_xcvr = MAC_XCVR_PCS; + } else if (!strcmp(phy_prop, "xgc")) { + /* 10G copper, XPCS */ + np->flags |= NIU_FLAGS_10G; + np->flags &= ~NIU_FLAGS_FIBER; + np->mac_xcvr = MAC_XCVR_XPCS; + } else { + return -EINVAL; + } + return 0; +} + +static void __devinit niu_pci_vpd_validate(struct niu *np) +{ + struct net_device *dev = np->dev; + struct niu_vpd *vpd = &np->vpd; + u8 val8; + + if (!is_valid_ether_addr(&vpd->local_mac[0])) { + dev_err(np->device, PFX "VPD MAC invalid, " + "falling back to SPROM.\n"); + + np->flags &= ~NIU_FLAGS_VPD_VALID; + return; + } + + if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { + dev_err(np->device, PFX "Illegal phy string [%s].\n", + np->vpd.phy_type); + dev_err(np->device, PFX "Falling back to SPROM.\n"); + np->flags &= ~NIU_FLAGS_VPD_VALID; + return; + } + + memcpy(dev->perm_addr, vpd->local_mac, ETH_ALEN); + + val8 = dev->perm_addr[5]; + dev->perm_addr[5] += np->port; + if (dev->perm_addr[5] < val8) + dev->perm_addr[4]++; + + memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); +} + +static int __devinit niu_pci_probe_sprom(struct niu *np) +{ + struct net_device *dev = np->dev; + int len, i; + u64 val, sum; + u8 val8; + + val = (nr64(ESPC_VER_IMGSZ) & ESPC_VER_IMGSZ_IMGSZ); + val >>= ESPC_VER_IMGSZ_IMGSZ_SHIFT; + len = val / 4; + + np->eeprom_len = len; + + niudbg(PROBE, "SPROM: Image size %llu\n", (unsigned long long) val); + + sum = 0; + for (i = 0; i < len; i++) { + val = nr64(ESPC_NCR(i)); + sum += (val >> 0) & 0xff; + sum += (val >> 8) & 0xff; + sum += (val >> 16) & 0xff; + sum += (val >> 24) & 0xff; + } + niudbg(PROBE, "SPROM: Checksum %x\n", (int)(sum & 0xff)); + if ((sum & 0xff) != 0xab) { + dev_err(np->device, PFX "Bad SPROM checksum " + "(%x, should be 0xab)\n", (int) (sum & 0xff)); + return -EINVAL; + } + + val = nr64(ESPC_PHY_TYPE); + switch (np->port) { + case 0: + val8 = (val & ESPC_PHY_TYPE_PORT0) >> + ESPC_PHY_TYPE_PORT0_SHIFT; + break; + case 1: + val8 = (val & ESPC_PHY_TYPE_PORT1) >> + ESPC_PHY_TYPE_PORT1_SHIFT; + break; + case 2: + val8 = (val & ESPC_PHY_TYPE_PORT2) >> + ESPC_PHY_TYPE_PORT2_SHIFT; + break; + case 3: + val8 = (val & ESPC_PHY_TYPE_PORT3) >> + ESPC_PHY_TYPE_PORT3_SHIFT; + break; + default: + dev_err(np->device, PFX "Bogus port number %u\n", + np->port); + return -EINVAL; + } + niudbg(PROBE, "SPROM: PHY type %x\n", val8); + + switch (val8) { + case ESPC_PHY_TYPE_1G_COPPER: + /* 1G copper, MII */ + np->flags &= ~(NIU_FLAGS_FIBER | + NIU_FLAGS_10G); + np->mac_xcvr = MAC_XCVR_MII; + break; + + case ESPC_PHY_TYPE_1G_FIBER: + /* 1G fiber, PCS */ + np->flags &= ~NIU_FLAGS_10G; + np->flags |= NIU_FLAGS_FIBER; + np->mac_xcvr = MAC_XCVR_PCS; + break; + + case ESPC_PHY_TYPE_10G_COPPER: + /* 10G copper, XPCS */ + np->flags |= NIU_FLAGS_10G; + np->flags &= ~NIU_FLAGS_FIBER; + np->mac_xcvr = MAC_XCVR_XPCS; + break; + + case ESPC_PHY_TYPE_10G_FIBER: + /* 10G fiber, XPCS */ + np->flags |= (NIU_FLAGS_10G | + NIU_FLAGS_FIBER); + np->mac_xcvr = MAC_XCVR_XPCS; + break; + + default: + dev_err(np->device, PFX "Bogus SPROM phy type %u\n", val8); + return -EINVAL; + } + + val = nr64(ESPC_MAC_ADDR0); + niudbg(PROBE, "SPROM: MAC_ADDR0[%08llx]\n", + (unsigned long long) val); + dev->perm_addr[0] = (val >> 0) & 0xff; + dev->perm_addr[1] = (val >> 8) & 0xff; + dev->perm_addr[2] = (val >> 16) & 0xff; + dev->perm_addr[3] = (val >> 24) & 0xff; + + val = nr64(ESPC_MAC_ADDR1); + niudbg(PROBE, "SPROM: MAC_ADDR1[%08llx]\n", + (unsigned long long) val); + dev->perm_addr[4] = (val >> 0) & 0xff; + dev->perm_addr[5] = (val >> 8) & 0xff; + + if (!is_valid_ether_addr(&dev->perm_addr[0])) { + dev_err(np->device, PFX "SPROM MAC address invalid\n"); + dev_err(np->device, PFX "[ \n"); + for (i = 0; i < 6; i++) + printk("%02x ", dev->perm_addr[i]); + printk("]\n"); + return -EINVAL; + } + + val8 = dev->perm_addr[5]; + dev->perm_addr[5] += np->port; + if (dev->perm_addr[5] < val8) + dev->perm_addr[4]++; + + memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); + + val = nr64(ESPC_MOD_STR_LEN); + niudbg(PROBE, "SPROM: MOD_STR_LEN[%llu]\n", + (unsigned long long) val); + if (val >= 8 * 4) + return -EINVAL; + + for (i = 0; i < val; i += 4) { + u64 tmp = nr64(ESPC_NCR(5 + (i / 4))); + + np->vpd.model[i + 3] = (tmp >> 0) & 0xff; + np->vpd.model[i + 2] = (tmp >> 8) & 0xff; + np->vpd.model[i + 1] = (tmp >> 16) & 0xff; + np->vpd.model[i + 0] = (tmp >> 24) & 0xff; + } + np->vpd.model[val] = '\0'; + + val = nr64(ESPC_BD_MOD_STR_LEN); + niudbg(PROBE, "SPROM: BD_MOD_STR_LEN[%llu]\n", + (unsigned long long) val); + if (val >= 4 * 4) + return -EINVAL; + + for (i = 0; i < val; i += 4) { + u64 tmp = nr64(ESPC_NCR(14 + (i / 4))); + + np->vpd.board_model[i + 3] = (tmp >> 0) & 0xff; + np->vpd.board_model[i + 2] = (tmp >> 8) & 0xff; + np->vpd.board_model[i + 1] = (tmp >> 16) & 0xff; + np->vpd.board_model[i + 0] = (tmp >> 24) & 0xff; + } + np->vpd.board_model[val] = '\0'; + + np->vpd.mac_num = + nr64(ESPC_NUM_PORTS_MACS) & ESPC_NUM_PORTS_MACS_VAL; + niudbg(PROBE, "SPROM: NUM_PORTS_MACS[%d]\n", + np->vpd.mac_num); + + return 0; +} + +static int __devinit niu_get_and_validate_port(struct niu *np) +{ + struct niu_parent *parent = np->parent; + + if (np->port <= 1) + np->flags |= NIU_FLAGS_XMAC; + + if (!parent->num_ports) { + if (parent->plat_type == PLAT_TYPE_NIU) { + parent->num_ports = 2; + } else { + parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & + ESPC_NUM_PORTS_MACS_VAL; + + if (!parent->num_ports) + parent->num_ports = 4; + } + } + + niudbg(PROBE, "niu_get_and_validate_port: port[%d] num_ports[%d]\n", + np->port, parent->num_ports); + if (np->port >= parent->num_ports) + return -ENODEV; + + return 0; +} + +static int __devinit phy_record(struct niu_parent *parent, + struct phy_probe_info *p, + int dev_id_1, int dev_id_2, u8 phy_port, + int type) +{ + u32 id = (dev_id_1 << 16) | dev_id_2; + u8 idx; + + if (dev_id_1 < 0 || dev_id_2 < 0) + return 0; + if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { + if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) + return 0; + } else { + if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) + return 0; + } + + pr_info("niu%d: Found PHY %08x type %s at phy_port %u\n", + parent->index, id, + (type == PHY_TYPE_PMA_PMD ? + "PMA/PMD" : + (type == PHY_TYPE_PCS ? + "PCS" : "MII")), + phy_port); + + if (p->cur[type] >= NIU_MAX_PORTS) { + printk(KERN_ERR PFX "Too many PHY ports.\n"); + return -EINVAL; + } + idx = p->cur[type]; + p->phy_id[type][idx] = id; + p->phy_port[type][idx] = phy_port; + p->cur[type] = idx + 1; + return 0; +} + +static int __devinit port_has_10g(struct phy_probe_info *p, int port) +{ + int i; + + for (i = 0; i < p->cur[PHY_TYPE_PMA_PMD]; i++) { + if (p->phy_port[PHY_TYPE_PMA_PMD][i] == port) + return 1; + } + for (i = 0; i < p->cur[PHY_TYPE_PCS]; i++) { + if (p->phy_port[PHY_TYPE_PCS][i] == port) + return 1; + } + + return 0; +} + +static int __devinit count_10g_ports(struct phy_probe_info *p, int *lowest) +{ + int port, cnt; + + cnt = 0; + *lowest = 32; + for (port = 8; port < 32; port++) { + if (port_has_10g(p, port)) { + if (!cnt) + *lowest = port; + cnt++; + } + } + + return cnt; +} + +static int __devinit count_1g_ports(struct phy_probe_info *p, int *lowest) +{ + *lowest = 32; + if (p->cur[PHY_TYPE_MII]) + *lowest = p->phy_port[PHY_TYPE_MII][0]; + + return p->cur[PHY_TYPE_MII]; +} + +static void __devinit niu_n2_divide_channels(struct niu_parent *parent) +{ + int num_ports = parent->num_ports; + int i; + + for (i = 0; i < num_ports; i++) { + parent->rxchan_per_port[i] = (16 / num_ports); + parent->txchan_per_port[i] = (16 / num_ports); + + pr_info(PFX "niu%d: Port %u [%u RX chans] " + "[%u TX chans]\n", + parent->index, i, + parent->rxchan_per_port[i], + parent->txchan_per_port[i]); + } +} + +static void __devinit niu_divide_channels(struct niu_parent *parent, + int num_10g, int num_1g) +{ + int num_ports = parent->num_ports; + int rx_chans_per_10g, rx_chans_per_1g; + int tx_chans_per_10g, tx_chans_per_1g; + int i, tot_rx, tot_tx; + + if (!num_10g || !num_1g) { + rx_chans_per_10g = rx_chans_per_1g = + (NIU_NUM_RXCHAN / num_ports); + tx_chans_per_10g = tx_chans_per_1g = + (NIU_NUM_TXCHAN / num_ports); + } else { + rx_chans_per_1g = NIU_NUM_RXCHAN / 8; + rx_chans_per_10g = (NIU_NUM_RXCHAN - + (rx_chans_per_1g * num_1g)) / + num_10g; + + tx_chans_per_1g = NIU_NUM_TXCHAN / 6; + tx_chans_per_10g = (NIU_NUM_TXCHAN - + (tx_chans_per_1g * num_1g)) / + num_10g; + } + + tot_rx = tot_tx = 0; + for (i = 0; i < num_ports; i++) { + int type = phy_decode(parent->port_phy, i); + + if (type == PORT_TYPE_10G) { + parent->rxchan_per_port[i] = rx_chans_per_10g; + parent->txchan_per_port[i] = tx_chans_per_10g; + } else { + parent->rxchan_per_port[i] = rx_chans_per_1g; + parent->txchan_per_port[i] = tx_chans_per_1g; + } + pr_info(PFX "niu%d: Port %u [%u RX chans] " + "[%u TX chans]\n", + parent->index, i, + parent->rxchan_per_port[i], + parent->txchan_per_port[i]); + tot_rx += parent->rxchan_per_port[i]; + tot_tx += parent->txchan_per_port[i]; + } + + if (tot_rx > NIU_NUM_RXCHAN) { + printk(KERN_ERR PFX "niu%d: Too many RX channels (%d), " + "resetting to one per port.\n", + parent->index, tot_rx); + for (i = 0; i < num_ports; i++) + parent->rxchan_per_port[i] = 1; + } + if (tot_tx > NIU_NUM_TXCHAN) { + printk(KERN_ERR PFX "niu%d: Too many TX channels (%d), " + "resetting to one per port.\n", + parent->index, tot_tx); + for (i = 0; i < num_ports; i++) + parent->txchan_per_port[i] = 1; + } + if (tot_rx < NIU_NUM_RXCHAN || tot_tx < NIU_NUM_TXCHAN) { + printk(KERN_WARNING PFX "niu%d: Driver bug, wasted channels, " + "RX[%d] TX[%d]\n", + parent->index, tot_rx, tot_tx); + } +} + +static void __devinit niu_divide_rdc_groups(struct niu_parent *parent, + int num_10g, int num_1g) +{ + int i, num_ports = parent->num_ports; + int rdc_group, rdc_groups_per_port; + int rdc_channel_base; + + rdc_group = 0; + rdc_groups_per_port = NIU_NUM_RDC_TABLES / num_ports; + + rdc_channel_base = 0; + + for (i = 0; i < num_ports; i++) { + struct niu_rdc_tables *tp = &parent->rdc_group_cfg[i]; + int grp, num_channels = parent->rxchan_per_port[i]; + int this_channel_offset; + + tp->first_table_num = rdc_group; + tp->num_tables = rdc_groups_per_port; + this_channel_offset = 0; + for (grp = 0; grp < tp->num_tables; grp++) { + struct rdc_table *rt = &tp->tables[grp]; + int slot; + + pr_info(PFX "niu%d: Port %d RDC tbl(%d) [ ", + parent->index, i, tp->first_table_num + grp); + for (slot = 0; slot < NIU_RDC_TABLE_SLOTS; slot++) { + rt->rxdma_channel[slot] = + rdc_channel_base + this_channel_offset; + + printk("%d ", rt->rxdma_channel[slot]); + + if (++this_channel_offset == num_channels) + this_channel_offset = 0; + } + printk("]\n"); + } + + parent->rdc_default[i] = rdc_channel_base; + + rdc_channel_base += num_channels; + rdc_group += rdc_groups_per_port; + } +} + +static int __devinit fill_phy_probe_info(struct niu *np, + struct niu_parent *parent, + struct phy_probe_info *info) +{ + unsigned long flags; + int port, err; + + memset(info, 0, sizeof(*info)); + + /* Port 0 to 7 are reserved for onboard Serdes, probe the rest. */ + niu_lock_parent(np, flags); + err = 0; + for (port = 8; port < 32; port++) { + int dev_id_1, dev_id_2; + + dev_id_1 = mdio_read(np, port, + NIU_PMA_PMD_DEV_ADDR, MII_PHYSID1); + dev_id_2 = mdio_read(np, port, + NIU_PMA_PMD_DEV_ADDR, MII_PHYSID2); + err = phy_record(parent, info, dev_id_1, dev_id_2, port, + PHY_TYPE_PMA_PMD); + if (err) + break; + dev_id_1 = mdio_read(np, port, + NIU_PCS_DEV_ADDR, MII_PHYSID1); + dev_id_2 = mdio_read(np, port, + NIU_PCS_DEV_ADDR, MII_PHYSID2); + err = phy_record(parent, info, dev_id_1, dev_id_2, port, + PHY_TYPE_PCS); + if (err) + break; + dev_id_1 = mii_read(np, port, MII_PHYSID1); + dev_id_2 = mii_read(np, port, MII_PHYSID2); + err = phy_record(parent, info, dev_id_1, dev_id_2, port, + PHY_TYPE_MII); + if (err) + break; + } + niu_unlock_parent(np, flags); + + return err; +} + +static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) +{ + struct phy_probe_info *info = &parent->phy_probe_info; + int lowest_10g, lowest_1g; + int num_10g, num_1g; + u32 val; + int err; + + err = fill_phy_probe_info(np, parent, info); + if (err) + return err; + + num_10g = count_10g_ports(info, &lowest_10g); + num_1g = count_1g_ports(info, &lowest_1g); + + switch ((num_10g << 4) | num_1g) { + case 0x24: + if (lowest_1g == 10) + parent->plat_type = PLAT_TYPE_VF_P0; + else if (lowest_1g == 26) + parent->plat_type = PLAT_TYPE_VF_P1; + else + goto unknown_vg_1g_port; + + /* fallthru */ + case 0x22: + val = (phy_encode(PORT_TYPE_10G, 0) | + phy_encode(PORT_TYPE_10G, 1) | + phy_encode(PORT_TYPE_1G, 2) | + phy_encode(PORT_TYPE_1G, 3)); + break; + + case 0x20: + val = (phy_encode(PORT_TYPE_10G, 0) | + phy_encode(PORT_TYPE_10G, 1)); + break; + + case 0x10: + val = phy_encode(PORT_TYPE_10G, np->port); + break; + + case 0x14: + if (lowest_1g == 10) + parent->plat_type = PLAT_TYPE_VF_P0; + else if (lowest_1g == 26) + parent->plat_type = PLAT_TYPE_VF_P1; + else + goto unknown_vg_1g_port; + + /* fallthru */ + case 0x13: + if ((lowest_10g & 0x7) == 0) + val = (phy_encode(PORT_TYPE_10G, 0) | + phy_encode(PORT_TYPE_1G, 1) | + phy_encode(PORT_TYPE_1G, 2) | + phy_encode(PORT_TYPE_1G, 3)); + else + val = (phy_encode(PORT_TYPE_1G, 0) | + phy_encode(PORT_TYPE_10G, 1) | + phy_encode(PORT_TYPE_1G, 2) | + phy_encode(PORT_TYPE_1G, 3)); + break; + + case 0x04: + if (lowest_1g == 10) + parent->plat_type = PLAT_TYPE_VF_P0; + else if (lowest_1g == 26) + parent->plat_type = PLAT_TYPE_VF_P1; + else + goto unknown_vg_1g_port; + + val = (phy_encode(PORT_TYPE_1G, 0) | + phy_encode(PORT_TYPE_1G, 1) | + phy_encode(PORT_TYPE_1G, 2) | + phy_encode(PORT_TYPE_1G, 3)); + break; + + default: + printk(KERN_ERR PFX "Unsupported port config " + "10G[%d] 1G[%d]\n", + num_10g, num_1g); + return -EINVAL; + } + + parent->port_phy = val; + + if (parent->plat_type == PLAT_TYPE_NIU) + niu_n2_divide_channels(parent); + else + niu_divide_channels(parent, num_10g, num_1g); + + niu_divide_rdc_groups(parent, num_10g, num_1g); + + return 0; + +unknown_vg_1g_port: + printk(KERN_ERR PFX "Cannot identify platform type, 1gport=%d\n", + lowest_1g); + return -EINVAL; +} + +static int __devinit niu_probe_ports(struct niu *np) +{ + struct niu_parent *parent = np->parent; + int err, i; + + niudbg(PROBE, "niu_probe_ports(): port_phy[%08x]\n", + parent->port_phy); + + if (parent->port_phy == PORT_PHY_UNKNOWN) { + err = walk_phys(np, parent); + if (err) + return err; + + niu_set_ldg_timer_res(np, 2); + for (i = 0; i <= LDN_MAX; i++) + niu_ldn_irq_enable(np, i, 0); + } + + if (parent->port_phy == PORT_PHY_INVALID) + return -EINVAL; + + return 0; +} + +static int __devinit niu_classifier_swstate_init(struct niu *np) +{ + struct niu_classifier *cp = &np->clas; + + niudbg(PROBE, "niu_classifier_swstate_init: num_tcam(%d)\n", + np->parent->tcam_num_entries); + + cp->tcam_index = (u16) np->port; + cp->h1_init = 0xffffffff; + cp->h2_init = 0xffff; + + return fflp_early_init(np); +} + +static void __devinit niu_link_config_init(struct niu *np) +{ + struct niu_link_config *lp = &np->link_config; + + lp->advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_10000baseT_Full | + ADVERTISED_Autoneg); + lp->speed = lp->active_speed = SPEED_INVALID; + lp->duplex = lp->active_duplex = DUPLEX_INVALID; +#if 0 + lp->loopback_mode = LOOPBACK_MAC; + lp->active_speed = SPEED_10000; + lp->active_duplex = DUPLEX_FULL; +#else + lp->loopback_mode = LOOPBACK_DISABLED; +#endif +} + +static int __devinit niu_init_mac_ipp_pcs_base(struct niu *np) +{ + switch (np->port) { + case 0: + np->mac_regs = np->regs + XMAC_PORT0_OFF; + np->ipp_off = 0x00000; + np->pcs_off = 0x04000; + np->xpcs_off = 0x02000; + break; + + case 1: + np->mac_regs = np->regs + XMAC_PORT1_OFF; + np->ipp_off = 0x08000; + np->pcs_off = 0x0a000; + np->xpcs_off = 0x08000; + break; + + case 2: + np->mac_regs = np->regs + BMAC_PORT2_OFF; + np->ipp_off = 0x04000; + np->pcs_off = 0x0e000; + np->xpcs_off = ~0UL; + break; + + case 3: + np->mac_regs = np->regs + BMAC_PORT3_OFF; + np->ipp_off = 0x0c000; + np->pcs_off = 0x12000; + np->xpcs_off = ~0UL; + break; + + default: + dev_err(np->device, PFX "Port %u is invalid, cannot " + "compute MAC block offset.\n", np->port); + return -EINVAL; + } + + return 0; +} + +static void __devinit niu_try_msix(struct niu *np, u8 *ldg_num_map) +{ + struct msix_entry msi_vec[NIU_NUM_LDG]; + struct niu_parent *parent = np->parent; + struct pci_dev *pdev = np->pdev; + int i, num_irqs, err; + u8 first_ldg; + + first_ldg = (NIU_NUM_LDG / parent->num_ports) * np->port; + for (i = 0; i < (NIU_NUM_LDG / parent->num_ports); i++) + ldg_num_map[i] = first_ldg + i; + + num_irqs = (parent->rxchan_per_port[np->port] + + parent->txchan_per_port[np->port] + + (np->port == 0 ? 3 : 1)); + BUG_ON(num_irqs > (NIU_NUM_LDG / parent->num_ports)); + +retry: + for (i = 0; i < num_irqs; i++) { + msi_vec[i].vector = 0; + msi_vec[i].entry = i; + } + + err = pci_enable_msix(pdev, msi_vec, num_irqs); + if (err < 0) { + np->flags &= ~NIU_FLAGS_MSIX; + return; + } + if (err > 0) { + num_irqs = err; + goto retry; + } + + np->flags |= NIU_FLAGS_MSIX; + for (i = 0; i < num_irqs; i++) + np->ldg[i].irq = msi_vec[i].vector; + np->num_ldg = num_irqs; +} + +static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) +{ +#ifdef CONFIG_SPARC64 + struct of_device *op = np->op; + const u32 *int_prop; + int i; + + int_prop = of_get_property(op->node, "interrupts", NULL); + if (!int_prop) + return -ENODEV; + + for (i = 0; i < op->num_irqs; i++) { + ldg_num_map[i] = int_prop[i]; + np->ldg[i].irq = op->irqs[i]; + } + + np->num_ldg = op->num_irqs; + + return 0; +#else + return -EINVAL; +#endif +} + +static int __devinit niu_ldg_init(struct niu *np) +{ + struct niu_parent *parent = np->parent; + u8 ldg_num_map[NIU_NUM_LDG]; + int first_chan, num_chan; + int i, err, ldg_rotor; + u8 port; + + np->num_ldg = 1; + np->ldg[0].irq = np->dev->irq; + if (parent->plat_type == PLAT_TYPE_NIU) { + err = niu_n2_irq_init(np, ldg_num_map); + if (err) + return err; + } else + niu_try_msix(np, ldg_num_map); + + port = np->port; + for (i = 0; i < np->num_ldg; i++) { + struct niu_ldg *lp = &np->ldg[i]; + +#ifdef NIU_NAPI_STRUCT + netif_napi_add(np->dev, &lp->napi, niu_poll, 64); +#else + lp->dummy_netdev = alloc_netdev(0, "", ether_setup); + if (!lp->dummy_netdev) + return -ENOMEM; + lp->dummy_netdev->priv = lp; + lp->dummy_netdev->weight = 64; + lp->dummy_netdev->poll = niu_poll; + set_bit(__LINK_STATE_START, &lp->dummy_netdev->state); +#endif + + lp->np = np; + lp->ldg_num = ldg_num_map[i]; + lp->timer = 2; /* XXX */ + + /* On N2 NIU the firmware has setup the SID mappings so they go + * to the correct values that will route the LDG to the proper + * interrupt in the NCU interrupt table. + */ + if (np->parent->plat_type != PLAT_TYPE_NIU) { + err = niu_set_ldg_sid(np, lp->ldg_num, port, i); + if (err) + return err; + } + } + + /* We adopt the LDG assignment ordering used by the N2 NIU + * 'interrupt' properties because that simplifies a lot of + * things. This ordering is: + * + * MAC + * MIF (if port zero) + * SYSERR (if port zero) + * RX channels + * TX channels + */ + + ldg_rotor = 0; + + err = niu_ldg_assign_ldn(np, parent, ldg_num_map[ldg_rotor], + LDN_MAC(port)); + if (err) + return err; + + ldg_rotor++; + if (ldg_rotor == np->num_ldg) + ldg_rotor = 0; + + if (port == 0) { + err = niu_ldg_assign_ldn(np, parent, + ldg_num_map[ldg_rotor], + LDN_MIF); + if (err) + return err; + + ldg_rotor++; + if (ldg_rotor == np->num_ldg) + ldg_rotor = 0; + + err = niu_ldg_assign_ldn(np, parent, + ldg_num_map[ldg_rotor], + LDN_DEVICE_ERROR); + if (err) + return err; + + ldg_rotor++; + if (ldg_rotor == np->num_ldg) + ldg_rotor = 0; + + } + + first_chan = 0; + for (i = 0; i < port; i++) + first_chan += parent->rxchan_per_port[port]; + num_chan = parent->rxchan_per_port[port]; + + for (i = first_chan; i < (first_chan + num_chan); i++) { + err = niu_ldg_assign_ldn(np, parent, + ldg_num_map[ldg_rotor], + LDN_RXDMA(i)); + if (err) + return err; + ldg_rotor++; + if (ldg_rotor == np->num_ldg) + ldg_rotor = 0; + } + + first_chan = 0; + for (i = 0; i < port; i++) + first_chan += parent->txchan_per_port[port]; + num_chan = parent->txchan_per_port[port]; + for (i = first_chan; i < (first_chan + num_chan); i++) { + err = niu_ldg_assign_ldn(np, parent, + ldg_num_map[ldg_rotor], + LDN_TXDMA(i)); + if (err) + return err; + ldg_rotor++; + if (ldg_rotor == np->num_ldg) + ldg_rotor = 0; + } + + return 0; +} + +static void __devexit niu_ldg_free(struct niu *np) +{ +#ifndef NIU_NAPI_STRUCT + int i; + + for (i = 0; i < np->num_ldg; i++) { + struct niu_ldg *lp = &np->ldg[i]; + + if (lp->dummy_netdev) { + free_netdev(lp->dummy_netdev); + lp->dummy_netdev = NULL; + } + } +#endif + if (np->flags & NIU_FLAGS_MSIX) + pci_disable_msix(np->pdev); +} + +static int __devinit niu_get_of_props(struct niu *np) +{ +#ifdef CONFIG_SPARC64 + struct net_device *dev = np->dev; + struct device_node *dp; + const char *phy_type; + const u8 *mac_addr; + int prop_len; + + if (np->parent->plat_type == PLAT_TYPE_NIU) + dp = np->op->node; + else + dp = pci_device_to_OF_node(np->pdev); + + phy_type = of_get_property(dp, "phy-type", &prop_len); + if (!phy_type) { + dev_err(np->device, PFX "%s: OF node lacks " + "phy-type property\n", + dp->full_name); + return -EINVAL; + } + + if (!strcmp(phy_type, "none")) + return -ENODEV; + + strcpy(np->vpd.phy_type, phy_type); + + if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { + dev_err(np->device, PFX "%s: Illegal phy string [%s].\n", + dp->full_name, np->vpd.phy_type); + return -EINVAL; + } + + mac_addr = of_get_property(dp, "local-mac-address", &prop_len); + if (!mac_addr) { + dev_err(np->device, PFX "%s: OF node lacks " + "local-mac-address property\n", + dp->full_name); + return -EINVAL; + } + if (prop_len != dev->addr_len) { + dev_err(np->device, PFX "%s: OF MAC address prop len (%d) " + "is wrong.\n", + dp->full_name, prop_len); + } + memcpy(dev->perm_addr, mac_addr, dev->addr_len); + if (!is_valid_ether_addr(&dev->perm_addr[0])) { + int i; + + dev_err(np->device, PFX "%s: OF MAC address is invalid\n", + dp->full_name); + dev_err(np->device, PFX "%s: [ \n", + dp->full_name); + for (i = 0; i < 6; i++) + printk("%02x ", dev->perm_addr[i]); + printk("]\n"); + return -EINVAL; + } + + memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); + + return 0; +#else + return -EINVAL; +#endif +} + +static int __devinit niu_get_invariants(struct niu *np) +{ + int err, have_props; + u32 offset; + + err = niu_get_of_props(np); + if (err == -ENODEV) + return err; + + have_props = !err; + + err = niu_get_and_validate_port(np); + if (err) + return err; + + err = niu_init_mac_ipp_pcs_base(np); + if (err) + return err; + + if (!have_props) { + if (np->parent->plat_type == PLAT_TYPE_NIU) + return -EINVAL; + + nw64(ESPC_PIO_EN, ESPC_PIO_EN_ENABLE); + offset = niu_pci_vpd_offset(np); + niudbg(PROBE, "niu_get_invariants: VPD offset [%08x]\n", + offset); + if (offset) + niu_pci_vpd_fetch(np, offset); + nw64(ESPC_PIO_EN, 0); + + if (np->flags & NIU_FLAGS_VPD_VALID) + niu_pci_vpd_validate(np); + + if (!(np->flags & NIU_FLAGS_VPD_VALID)) { + err = niu_pci_probe_sprom(np); + if (err) + return err; + } + } + + err = niu_probe_ports(np); + if (err) + return err; + + niu_ldg_init(np); + + niu_classifier_swstate_init(np); + niu_link_config_init(np); + + err = niu_determine_phy_disposition(np); + if (!err) + err = niu_init_link(np); + + return err; +} + +static LIST_HEAD(niu_parent_list); +static DEFINE_MUTEX(niu_parent_lock); +static int niu_parent_index; + +static ssize_t show_port_phy(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct niu_parent *p = plat_dev->dev.platform_data; + u32 port_phy = p->port_phy; + char *orig_buf = buf; + int i; + + if (port_phy == PORT_PHY_UNKNOWN || + port_phy == PORT_PHY_INVALID) + return 0; + + for (i = 0; i < p->num_ports; i++) { + const char *type_str; + int type; + + type = phy_decode(port_phy, i); + if (type == PORT_TYPE_10G) + type_str = "10G"; + else + type_str = "1G"; + buf += sprintf(buf, + (i == 0) ? "%s" : " %s", + type_str); + } + buf += sprintf(buf, "\n"); + return buf - orig_buf; +} + +static ssize_t show_plat_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct niu_parent *p = plat_dev->dev.platform_data; + const char *type_str; + + switch (p->plat_type) { + case PLAT_TYPE_ATLAS: + type_str = "atlas"; + break; + case PLAT_TYPE_NIU: + type_str = "niu"; + break; + case PLAT_TYPE_VF_P0: + type_str = "vf_p0"; + break; + case PLAT_TYPE_VF_P1: + type_str = "vf_p1"; + break; + default: + type_str = "unknown"; + break; + } + + return sprintf(buf, "%s\n", type_str); +} + +static ssize_t __show_chan_per_port(struct device *dev, + struct device_attribute *attr, char *buf, + int rx) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct niu_parent *p = plat_dev->dev.platform_data; + char *orig_buf = buf; + u8 *arr; + int i; + + arr = (rx ? p->rxchan_per_port : p->txchan_per_port); + + for (i = 0; i < p->num_ports; i++) { + buf += sprintf(buf, + (i == 0) ? "%d" : " %d", + arr[i]); + } + buf += sprintf(buf, "\n"); + + return buf - orig_buf; +} + +static ssize_t show_rxchan_per_port(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return __show_chan_per_port(dev, attr, buf, 1); +} + +static ssize_t show_txchan_per_port(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return __show_chan_per_port(dev, attr, buf, 1); +} + +static ssize_t show_num_ports(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct niu_parent *p = plat_dev->dev.platform_data; + + return sprintf(buf, "%d\n", p->num_ports); +} + +static struct device_attribute niu_parent_attributes[] = { + __ATTR(port_phy, S_IRUGO, show_port_phy, NULL), + __ATTR(plat_type, S_IRUGO, show_plat_type, NULL), + __ATTR(rxchan_per_port, S_IRUGO, show_rxchan_per_port, NULL), + __ATTR(txchan_per_port, S_IRUGO, show_txchan_per_port, NULL), + __ATTR(num_ports, S_IRUGO, show_num_ports, NULL), + {} +}; + +static struct niu_parent * __devinit niu_new_parent(struct niu *np, + union niu_parent_id *id, + u8 ptype) +{ + struct platform_device *plat_dev; + struct niu_parent *p; + int i; + + niudbg(PROBE, "niu_new_parent: Creating new parent.\n"); + + plat_dev = platform_device_register_simple("niu", niu_parent_index, + NULL, 0); + if (!plat_dev) + return NULL; + + for (i = 0; attr_name(niu_parent_attributes[i]); i++) { + int err = device_create_file(&plat_dev->dev, + &niu_parent_attributes[i]); + if (err) + goto fail_unregister; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + goto fail_unregister; + + p->index = niu_parent_index++; + + plat_dev->dev.platform_data = p; + p->plat_dev = plat_dev; + + memcpy(&p->id, id, sizeof(*id)); + p->plat_type = ptype; + INIT_LIST_HEAD(&p->list); + atomic_set(&p->refcnt, 0); + list_add(&p->list, &niu_parent_list); + spin_lock_init(&p->lock); + + p->rxdma_clock_divider = 7500; + + p->tcam_num_entries = NIU_PCI_TCAM_ENTRIES; + if (p->plat_type == PLAT_TYPE_NIU) + p->tcam_num_entries = NIU_NONPCI_TCAM_ENTRIES; + + for (i = CLASS_CODE_USER_PROG1; i <= CLASS_CODE_SCTP_IPV6; i++) { + int index = i - CLASS_CODE_USER_PROG1; + + p->tcam_key[index] = TCAM_KEY_TSEL; + p->flow_key[index] = (FLOW_KEY_IPSA | + FLOW_KEY_IPDA | + FLOW_KEY_PROTO | + (FLOW_KEY_L4_BYTE12 << + FLOW_KEY_L4_0_SHIFT) | + (FLOW_KEY_L4_BYTE12 << + FLOW_KEY_L4_1_SHIFT)); + } + + for (i = 0; i < LDN_MAX + 1; i++) + p->ldg_map[i] = LDG_INVALID; + + return p; + +fail_unregister: + platform_device_unregister(plat_dev); + return NULL; +} + +static struct niu_parent * __devinit niu_get_parent(struct niu *np, + union niu_parent_id *id, + u8 ptype) +{ + struct niu_parent *p, *tmp; + int port = np->port; + + niudbg(PROBE, "niu_get_parent: platform_type[%u] port[%u]\n", + ptype, port); + + mutex_lock(&niu_parent_lock); + p = NULL; + list_for_each_entry(tmp, &niu_parent_list, list) { + if (!memcmp(id, &tmp->id, sizeof(*id))) { + p = tmp; + break; + } + } + if (!p) + p = niu_new_parent(np, id, ptype); + + if (p) { + char port_name[6]; + int err; + + sprintf(port_name, "port%d", port); + err = sysfs_create_link(&p->plat_dev->dev.kobj, + &np->device->kobj, + port_name); + if (!err) { + p->ports[port] = np; + atomic_inc(&p->refcnt); + } + } + mutex_unlock(&niu_parent_lock); + + return p; +} + +static void niu_put_parent(struct niu *np) +{ + struct niu_parent *p = np->parent; + u8 port = np->port; + char port_name[6]; + + BUG_ON(!p || p->ports[port] != np); + + niudbg(PROBE, "niu_put_parent: port[%u]\n", port); + + sprintf(port_name, "port%d", port); + + mutex_lock(&niu_parent_lock); + + sysfs_remove_link(&p->plat_dev->dev.kobj, port_name); + + p->ports[port] = NULL; + np->parent = NULL; + + if (atomic_dec_and_test(&p->refcnt)) { + list_del(&p->list); + platform_device_unregister(p->plat_dev); + } + + mutex_unlock(&niu_parent_lock); +} + +static void *niu_pci_alloc_coherent(struct device *dev, size_t size, + u64 *handle, gfp_t flag) +{ + dma_addr_t dh; + void *ret; + + ret = dma_alloc_coherent(dev, size, &dh, flag); + if (ret) + *handle = dh; + return ret; +} + +static void niu_pci_free_coherent(struct device *dev, size_t size, + void *cpu_addr, u64 handle) +{ + dma_free_coherent(dev, size, cpu_addr, handle); +} + +static u64 niu_pci_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + return dma_map_page(dev, page, offset, size, direction); +} + +static void niu_pci_unmap_page(struct device *dev, u64 dma_address, + size_t size, enum dma_data_direction direction) +{ + return dma_unmap_page(dev, dma_address, size, direction); +} + +static u64 niu_pci_map_single(struct device *dev, void *cpu_addr, + size_t size, + enum dma_data_direction direction) +{ + return dma_map_single(dev, cpu_addr, size, direction); +} + +static void niu_pci_unmap_single(struct device *dev, u64 dma_address, + size_t size, + enum dma_data_direction direction) +{ + dma_unmap_single(dev, dma_address, size, direction); +} + +static const struct niu_ops niu_pci_ops = { + .alloc_coherent = niu_pci_alloc_coherent, + .free_coherent = niu_pci_free_coherent, + .map_page = niu_pci_map_page, + .unmap_page = niu_pci_unmap_page, + .map_single = niu_pci_map_single, + .unmap_single = niu_pci_unmap_single, +}; + +static void __devinit niu_driver_version(void) +{ + static int niu_version_printed; + + if (niu_version_printed++ == 0) + pr_info("%s", version); +} + +static struct net_device * __devinit niu_alloc_and_init( + struct device *gen_dev, struct pci_dev *pdev, + struct of_device *op, const struct niu_ops *ops, + u8 port) +{ + struct net_device *dev = alloc_etherdev(sizeof(struct niu)); + struct niu *np; + + if (!dev) { + dev_err(gen_dev, PFX "Etherdev alloc failed, aborting.\n"); + return NULL; + } + + SET_NETDEV_DEV(dev, gen_dev); + + np = netdev_priv(dev); + np->dev = dev; + np->pdev = pdev; + np->op = op; + np->device = gen_dev; + np->ops = ops; + + np->msg_enable = niu_debug; + + spin_lock_init(&np->lock); + INIT_WORK(&np->reset_task, niu_reset_task); + + np->port = port; + + return dev; +} + +static void __devinit niu_assign_netdev_ops(struct net_device *dev) +{ + dev->open = niu_open; + dev->stop = niu_close; + dev->get_stats = niu_get_stats; + dev->set_multicast_list = niu_set_rx_mode; + dev->set_mac_address = niu_set_mac_addr; + dev->do_ioctl = niu_ioctl; + dev->tx_timeout = niu_tx_timeout; + dev->hard_start_xmit = niu_start_xmit; + dev->ethtool_ops = &niu_ethtool_ops; + dev->watchdog_timeo = NIU_TX_TIMEOUT; + dev->change_mtu = niu_change_mtu; +#ifndef NIU_NAPI_STRUCT + dev->poll = niu_poll; + dev->weight = 64; +#endif +} + +static void __devinit niu_device_announce(struct niu *np) +{ + struct net_device *dev = np->dev; + int i; + + pr_info("%s: NIU Ethernet ", dev->name); + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], + i == 5 ? '\n' : ':'); + + pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n", + dev->name, + (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), + (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), + (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), + (np->mac_xcvr == MAC_XCVR_MII ? "MII" : + (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), + np->vpd.phy_type); +} + +static int __devinit niu_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned long niureg_base, niureg_len; + union niu_parent_id parent_id; + struct net_device *dev; + struct niu *np; + int err, pos; + u64 dma_mask; + u16 val16; + + niu_driver_version(); + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, PFX "Cannot enable PCI device, " + "aborting.\n"); + return err; + } + + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || + !(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { + dev_err(&pdev->dev, PFX "Cannot find proper PCI device " + "base addresses, aborting.\n"); + err = -ENODEV; + goto err_out_disable_pdev; + } + + err = pci_request_regions(pdev, DRV_MODULE_NAME); + if (err) { + dev_err(&pdev->dev, PFX "Cannot obtain PCI resources, " + "aborting.\n"); + goto err_out_disable_pdev; + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (pos <= 0) { + dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, " + "aborting.\n"); + goto err_out_free_res; + } + + dev = niu_alloc_and_init(&pdev->dev, pdev, NULL, + &niu_pci_ops, PCI_FUNC(pdev->devfn)); + if (!dev) { + err = -ENOMEM; + goto err_out_free_res; + } + np = netdev_priv(dev); + + memset(&parent_id, 0, sizeof(parent_id)); + parent_id.pci.domain = pci_domain_nr(pdev->bus); + parent_id.pci.bus = pdev->bus->number; + parent_id.pci.device = PCI_SLOT(pdev->devfn); + + np->parent = niu_get_parent(np, &parent_id, + PLAT_TYPE_ATLAS); + if (!np->parent) { + err = -ENOMEM; + goto err_out_free_dev; + } + + pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16); + val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; + val16 |= (PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE | + PCI_EXP_DEVCTL_RELAX_EN); + pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16); + + dma_mask = DMA_44BIT_MASK; + err = pci_set_dma_mask(pdev, dma_mask); + if (!err) { + dev->features |= NETIF_F_HIGHDMA; + err = pci_set_consistent_dma_mask(pdev, dma_mask); + if (err) { + dev_err(&pdev->dev, PFX "Unable to obtain 44 bit " + "DMA for consistent allocations, " + "aborting.\n"); + goto err_out_release_parent; + } + } + if (err || dma_mask == DMA_32BIT_MASK) { + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { + dev_err(&pdev->dev, PFX "No usable DMA configuration, " + "aborting.\n"); + goto err_out_release_parent; + } + } + + dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); + + niureg_base = pci_resource_start(pdev, 0); + niureg_len = pci_resource_len(pdev, 0); + + np->regs = ioremap_nocache(niureg_base, niureg_len); + if (!np->regs) { + dev_err(&pdev->dev, PFX "Cannot map device registers, " + "aborting.\n"); + err = -ENOMEM; + goto err_out_release_parent; + } + + pci_set_master(pdev); + pci_save_state(pdev); + + dev->irq = pdev->irq; + + niu_assign_netdev_ops(dev); + + err = niu_get_invariants(np); + if (err) { + if (err != -ENODEV) + dev_err(&pdev->dev, PFX "Problem fetching invariants " + "of chip, aborting.\n"); + goto err_out_iounmap; + } + + err = register_netdev(dev); + if (err) { + dev_err(&pdev->dev, PFX "Cannot register net device, " + "aborting.\n"); + goto err_out_iounmap; + } + + pci_set_drvdata(pdev, dev); + + niu_device_announce(np); + + return 0; + +err_out_iounmap: + if (np->regs) { + iounmap(np->regs); + np->regs = NULL; + } + +err_out_release_parent: + niu_put_parent(np); + +err_out_free_dev: + free_netdev(dev); + +err_out_free_res: + pci_release_regions(pdev); + +err_out_disable_pdev: + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + return err; +} + +static void __devexit niu_pci_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (dev) { + struct niu *np = netdev_priv(dev); + + unregister_netdev(dev); + if (np->regs) { + iounmap(np->regs); + np->regs = NULL; + } + + niu_ldg_free(np); + + niu_put_parent(np); + + free_netdev(dev); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + } +} + +static int niu_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct niu *np = netdev_priv(dev); + unsigned long flags; + + if (!netif_running(dev)) + return 0; + + flush_scheduled_work(); + niu_netif_stop(np); + + del_timer_sync(&np->timer); + + spin_lock_irqsave(&np->lock, flags); + niu_enable_interrupts(np, 0); + spin_unlock_irqrestore(&np->lock, flags); + + netif_device_detach(dev); + + spin_lock_irqsave(&np->lock, flags); + niu_stop_hw(np); + spin_unlock_irqrestore(&np->lock, flags); + + pci_save_state(pdev); + + return 0; +} + +static int niu_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct niu *np = netdev_priv(dev); + unsigned long flags; + int err; + + if (!netif_running(dev)) + return 0; + + pci_restore_state(pdev); + + netif_device_attach(dev); + + spin_lock_irqsave(&np->lock, flags); + + err = niu_init_hw(np); + if (!err) { + np->timer.expires = jiffies + HZ; + add_timer(&np->timer); + niu_netif_start(np); + } + + spin_unlock_irqrestore(&np->lock, flags); + + return err; +} + +static struct pci_driver niu_pci_driver = { + .name = DRV_MODULE_NAME, + .id_table = niu_pci_tbl, + .probe = niu_pci_init_one, + .remove = __devexit_p(niu_pci_remove_one), + .suspend = niu_suspend, + .resume = niu_resume, +}; + +#ifdef CONFIG_SPARC64 +static void *niu_phys_alloc_coherent(struct device *dev, size_t size, + u64 *dma_addr, gfp_t flag) +{ + unsigned long order = get_order(size); + unsigned long page = __get_free_pages(flag, order); + + if (page == 0UL) + return NULL; + memset((char *)page, 0, PAGE_SIZE << order); + *dma_addr = __pa(page); + + return (void *) page; +} + +static void niu_phys_free_coherent(struct device *dev, size_t size, + void *cpu_addr, u64 handle) +{ + unsigned long order = get_order(size); + + free_pages((unsigned long) cpu_addr, order); +} + +static u64 niu_phys_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + return page_to_phys(page) + offset; +} + +static void niu_phys_unmap_page(struct device *dev, u64 dma_address, + size_t size, enum dma_data_direction direction) +{ + /* Nothing to do. */ +} + +static u64 niu_phys_map_single(struct device *dev, void *cpu_addr, + size_t size, + enum dma_data_direction direction) +{ + return __pa(cpu_addr); +} + +static void niu_phys_unmap_single(struct device *dev, u64 dma_address, + size_t size, + enum dma_data_direction direction) +{ + /* Nothing to do. */ +} + +static const struct niu_ops niu_phys_ops = { + .alloc_coherent = niu_phys_alloc_coherent, + .free_coherent = niu_phys_free_coherent, + .map_page = niu_phys_map_page, + .unmap_page = niu_phys_unmap_page, + .map_single = niu_phys_map_single, + .unmap_single = niu_phys_unmap_single, +}; + +static unsigned long res_size(struct resource *r) +{ + return r->end - r->start + 1UL; +} + +static int __devinit niu_of_probe(struct of_device *op, + const struct of_device_id *match) +{ + union niu_parent_id parent_id; + struct net_device *dev; + struct niu *np; + const u32 *reg; + int err; + + niu_driver_version(); + + reg = of_get_property(op->node, "reg", NULL); + if (!reg) { + dev_err(&op->dev, PFX "%s: No 'reg' property, aborting.\n", + op->node->full_name); + return -ENODEV; + } + + dev = niu_alloc_and_init(&op->dev, NULL, op, + &niu_phys_ops, reg[0] & 0x1); + if (!dev) { + err = -ENOMEM; + goto err_out; + } + np = netdev_priv(dev); + + memset(&parent_id, 0, sizeof(parent_id)); + parent_id.of = of_get_parent(op->node); + + np->parent = niu_get_parent(np, &parent_id, + PLAT_TYPE_NIU); + if (!np->parent) { + err = -ENOMEM; + goto err_out_free_dev; + } + + dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM); + + np->regs = of_ioremap(&op->resource[1], 0, + res_size(&op->resource[1]), + "niu regs"); + if (!np->regs) { + dev_err(&op->dev, PFX "Cannot map device registers, " + "aborting.\n"); + err = -ENOMEM; + goto err_out_release_parent; + } + + np->vir_regs_1 = of_ioremap(&op->resource[2], 0, + res_size(&op->resource[2]), + "niu vregs-1"); + if (!np->vir_regs_1) { + dev_err(&op->dev, PFX "Cannot map device vir registers 1, " + "aborting.\n"); + err = -ENOMEM; + goto err_out_iounmap; + } + + np->vir_regs_2 = of_ioremap(&op->resource[3], 0, + res_size(&op->resource[3]), + "niu vregs-2"); + if (!np->vir_regs_2) { + dev_err(&op->dev, PFX "Cannot map device vir registers 2, " + "aborting.\n"); + err = -ENOMEM; + goto err_out_iounmap; + } + + niu_assign_netdev_ops(dev); + + err = niu_get_invariants(np); + if (err) { + if (err != -ENODEV) + dev_err(&op->dev, PFX "Problem fetching invariants " + "of chip, aborting.\n"); + goto err_out_iounmap; + } + + err = register_netdev(dev); + if (err) { + dev_err(&op->dev, PFX "Cannot register net device, " + "aborting.\n"); + goto err_out_iounmap; + } + + dev_set_drvdata(&op->dev, dev); + + niu_device_announce(np); + + return 0; + +err_out_iounmap: + if (np->vir_regs_1) { + of_iounmap(&op->resource[2], np->vir_regs_1, + res_size(&op->resource[2])); + np->vir_regs_1 = NULL; + } + + if (np->vir_regs_2) { + of_iounmap(&op->resource[3], np->vir_regs_2, + res_size(&op->resource[3])); + np->vir_regs_2 = NULL; + } + + if (np->regs) { + of_iounmap(&op->resource[1], np->regs, + res_size(&op->resource[1])); + np->regs = NULL; + } + +err_out_release_parent: + niu_put_parent(np); + +err_out_free_dev: + free_netdev(dev); + +err_out: + return err; +} + +static int __devexit niu_of_remove(struct of_device *op) +{ + struct net_device *dev = dev_get_drvdata(&op->dev); + + if (dev) { + struct niu *np = netdev_priv(dev); + + unregister_netdev(dev); + + if (np->vir_regs_1) { + of_iounmap(&op->resource[2], np->vir_regs_1, + res_size(&op->resource[2])); + np->vir_regs_1 = NULL; + } + + if (np->vir_regs_2) { + of_iounmap(&op->resource[3], np->vir_regs_2, + res_size(&op->resource[3])); + np->vir_regs_2 = NULL; + } + + if (np->regs) { + of_iounmap(&op->resource[1], np->regs, + res_size(&op->resource[1])); + np->regs = NULL; + } + + niu_ldg_free(np); + + niu_put_parent(np); + + free_netdev(dev); + dev_set_drvdata(&op->dev, NULL); + } + return 0; +} + +static struct of_device_id niu_match[] = { + { + .name = "network", + .compatible = "SUNW,niusl", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, niu_match); + +static struct of_platform_driver niu_of_driver = { + .name = "niu", + .match_table = niu_match, + .probe = niu_of_probe, + .remove = __devexit_p(niu_of_remove), +}; + +#endif /* CONFIG_SPARC64 */ + +static int __init niu_init(void) +{ + int err = 0; + + BUILD_BUG_ON((PAGE_SIZE < 4 * 1024) || + ((PAGE_SIZE > 32 * 1024) && + ((PAGE_SIZE % (32 * 1024)) != 0 && + (PAGE_SIZE % (16 * 1024)) != 0 && + (PAGE_SIZE % (8 * 1024)) != 0 && + (PAGE_SIZE % (4 * 1024)) != 0))); + + niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT); + +#ifdef CONFIG_SPARC64 + err = of_register_driver(&niu_of_driver, &of_bus_type); +#endif + + if (!err) { + err = pci_register_driver(&niu_pci_driver); +#ifdef CONFIG_SPARC64 + if (err) + of_unregister_driver(&niu_of_driver); +#endif + } + + return err; +} + +static void __exit niu_exit(void) +{ + pci_unregister_driver(&niu_pci_driver); +#ifdef CONFIG_SPARC64 + of_unregister_driver(&niu_of_driver); +#endif +} + +module_init(niu_init); +module_exit(niu_exit); --- linux-source-2.6.22-2.6.22.orig/drivers/net/sky2.c +++ linux-source-2.6.22-2.6.22/drivers/net/sky2.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.14" +#define DRV_VERSION "1.18" #define PFX DRV_NAME " " /* @@ -64,7 +65,6 @@ #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) #define RX_DEF_PENDING RX_MAX_PENDING #define RX_SKB_ALIGN 8 -#define RX_BUF_WRITE 16 #define TX_RING_SIZE 512 #define TX_DEF_PENDING (TX_RING_SIZE - 1) @@ -77,6 +77,9 @@ #define NAPI_WEIGHT 64 #define PHY_RETRIES 1000 +#define SKY2_EEPROM_MAGIC 0x9955aabb + + #define RING_NEXT(x,s) (((x)+1) & ((s)-1)) static const u32 default_msg = @@ -96,10 +99,6 @@ module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 0; -module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); - static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ @@ -119,18 +118,21 @@ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ -// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ { 0 } }; @@ -148,8 +150,11 @@ "Extreme", /* 0xb5 */ "EC", /* 0xb6 */ "FE", /* 0xb7 */ + "FE+", /* 0xb8 */ }; +static void sky2_set_multicast(struct net_device *dev); + /* Access to external PHY */ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) { @@ -216,14 +221,29 @@ else sky2_write8(hw, B2_Y2_CLK_GATE, 0); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { - u32 reg1; + if (hw->flags & SKY2_HW_ADV_POWER_CTL) { + u32 reg; sky2_pci_write32(hw, PCI_DEV_REG3, 0); - reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); - reg1 &= P_ASPM_CONTROL_MSK; - sky2_pci_write32(hw, PCI_DEV_REG4, reg1); - sky2_pci_write32(hw, PCI_DEV_REG5, 0); + + reg = sky2_pci_read32(hw, PCI_DEV_REG4); + /* set all bits to 0 except bits 15..12 and 8 */ + reg &= P_ASPM_CONTROL_MSK; + sky2_pci_write32(hw, PCI_DEV_REG4, reg); + + reg = sky2_pci_read32(hw, PCI_DEV_REG5); + /* set all bits to 0 except bits 28 & 27 */ + reg &= P_CTL_TIM_VMAIN_AV_MSK; + sky2_pci_write32(hw, PCI_DEV_REG5, reg); + + sky2_pci_write32(hw, PCI_CFG_REG_1, 0); + + /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ + reg = sky2_read32(hw, B2_GP_IO); + reg |= GLB_GPIO_STAT_RACE_DIS; + sky2_write32(hw, B2_GP_IO, reg); + + sky2_read32(hw, B2_GP_IO); } } @@ -294,10 +314,8 @@ struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; - if (sky2->autoneg == AUTONEG_ENABLE - && !(hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX)) { + if (sky2->autoneg == AUTONEG_ENABLE && + !(hw->flags & SKY2_HW_NEWER_PHY)) { u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | @@ -317,9 +335,19 @@ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); if (sky2_is_copper(hw)) { - if (hw->chip_id == CHIP_ID_YUKON_FE) { + if (!(hw->flags & SKY2_HW_GIGABIT)) { /* enable automatic crossover */ ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1; + + if (hw->chip_id == CHIP_ID_YUKON_FE_P && + hw->chip_rev == CHIP_REV_YU_FE2_A0) { + u16 spec; + + /* Enable Class A driver for FE+ A0 */ + spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2); + spec |= PHY_M_FESC_SEL_CL_A; + gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec); + } } else { /* disable energy detect */ ctrl &= ~PHY_M_PC_EN_DET_MSK; @@ -329,9 +357,7 @@ /* downshift on PHY 88E1112 and 88E1149 is changed */ if (sky2->autoneg == AUTONEG_ENABLE - && (hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX)) { + && (hw->flags & SKY2_HW_NEWER_PHY)) { /* set downshift counter to 3x and enable downshift */ ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; @@ -347,7 +373,7 @@ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); /* special setup for PHY 88E1112 Fiber */ - if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) { + if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) { pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ @@ -438,7 +464,7 @@ gma_write16(hw, port, GM_GP_CTRL, reg); - if (hw->chip_id != CHIP_ID_YUKON_FE) + if (hw->flags & SKY2_HW_GIGABIT) gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); @@ -462,6 +488,23 @@ gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); break; + case CHIP_ID_YUKON_FE_P: + /* Enable Link Partner Next Page */ + ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); + ctrl |= PHY_M_PC_ENA_LIP_NP; + + /* disable Energy Detect and enable scrambler */ + ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + + /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */ + ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) | + PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) | + PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED); + + gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); + break; + case CHIP_ID_YUKON_XL: pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); @@ -531,7 +574,13 @@ /* set page register to 0 */ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); + } else if (hw->chip_id == CHIP_ID_YUKON_FE_P && + hw->chip_rev == CHIP_REV_YU_FE2_A0) { + /* apply workaround for integrated resistors calibration */ + gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17); + gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60); } else if (hw->chip_id != CHIP_ID_YUKON_EX) { + /* no effect on Yukon-XL */ gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { @@ -650,15 +699,40 @@ } +static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) +{ + struct net_device *dev = hw->dev[port]; + + if (dev->mtu <= ETH_DATA_LEN) + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_JUMBO_DIS | TX_STFW_ENA); + + else if (hw->chip_id != CHIP_ID_YUKON_EC_U) + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_STFW_ENA | TX_JUMBO_ENA); + else { + /* set Tx GMAC FIFO Almost Empty Threshold */ + sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), + (ECU_JUMBO_WM << 16) | ECU_AE_THR); + + sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), + TX_JUMBO_ENA | TX_STFW_DIS); + + /* Can't do offload because of lack of store/forward */ + dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM); + } +} + static void sky2_mac_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 reg; + u32 rx_reg; int i; const u8 *addr = hw->dev[port]->dev_addr; - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); @@ -730,33 +804,34 @@ /* Configure Rx MAC FIFO */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), - GMF_OPER_ON | GMF_RX_F_FL_ON); + rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; + if (hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_FE_P) + rx_reg |= GMF_RX_OVER_ON; + + sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); /* Flush Rx MAC FIFO on any flow control or error */ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ - sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1); + reg = RX_GMF_FL_THR_DEF + 1; + /* Another magic mystery workaround from sk98lin */ + if (hw->chip_id == CHIP_ID_YUKON_FE_P && + hw->chip_rev == CHIP_REV_YU_FE2_A0) + reg = 0x178; + sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg); /* Configure Tx MAC FIFO */ sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { + /* On chips without ram buffer, pause is controled by MAC level */ + if (sky2_read8(hw, B2_E_0) == 0) { sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); - /* set Tx GMAC FIFO Almost Empty Threshold */ - sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), - (ECU_JUMBO_WM << 16) | ECU_AE_THR); - - if (hw->dev[port]->mtu > ETH_DATA_LEN) - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_DIS); - else - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); + sky2_set_tx_stfwd(hw, port); } } @@ -835,6 +910,20 @@ return le; } +static void tx_init(struct sky2_port *sky2) +{ + struct sky2_tx_le *le; + + sky2->tx_prod = sky2->tx_cons = 0; + sky2->tx_tcpsum = 0; + sky2->tx_last_mss = 0; + + le = get_tx_le(sky2); + le->addr = 0; + le->opcode = OP_ADDR64 | HW_OWNER; + sky2->tx_addr64 = 0; +} + static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, struct sky2_tx_le *le) { @@ -861,24 +950,18 @@ return le; } -/* Return high part of DMA address (could be 32 or 64 bit) */ -static inline u32 high32(dma_addr_t a) -{ - return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0; -} - /* Build description to hardware for one receive segment */ static void sky2_rx_add(struct sky2_port *sky2, u8 op, dma_addr_t map, unsigned len) { struct sky2_rx_le *le; - u32 hi = high32(map); + u32 hi = upper_32_bits(map); if (sky2->rx_addr64 != hi) { le = sky2_next_rx(sky2); le->addr = cpu_to_le32(hi); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->rx_addr64 = high32(map + len); + sky2->rx_addr64 = upper_32_bits(map + len); } le = sky2_next_rx(sky2); @@ -937,9 +1020,8 @@ */ static void rx_set_checksum(struct sky2_port *sky2) { - struct sky2_rx_le *le; + struct sky2_rx_le *le = sky2_next_rx(sky2); - le = sky2_next_rx(sky2); le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); le->ctrl = 0; le->opcode = OP_TCPSTART | HW_OWNER; @@ -947,7 +1029,6 @@ sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); - } /* @@ -1106,6 +1187,11 @@ return NULL; } +static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq) +{ + sky2_put_idx(sky2->hw, rxq, sky2->rx_put); +} + /* * Allocate and setup receiver buffer pool. * Normal case this ends up creating one list element for skb @@ -1134,15 +1220,15 @@ if (hw->chip_id == CHIP_ID_YUKON_EC_U && (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) - sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); + sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); - rx_set_checksum(sky2); + if (!(hw->flags & SKY2_HW_NEW_LE)) + rx_set_checksum(sky2); /* Space needed for frame data + headers rounded up */ - size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8) - + 8; + size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); /* Stopping point for hardware truncation */ thresh = (size - 8) / sizeof(u32); @@ -1197,7 +1283,7 @@ } /* Tell chip about available buffers */ - sky2_put_idx(hw, rxq, sky2->rx_put); + sky2_rx_update(sky2, rxq); return 0; nomem: sky2_rx_clean(sky2); @@ -1210,7 +1296,7 @@ struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u32 ramsize, imask; + u32 imask, ramsize; int cap, err = -ENOMEM; struct net_device *otherdev = hw->dev[sky2->port^1]; @@ -1234,6 +1320,8 @@ if (netif_msg_ifup(sky2)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); + netif_carrier_off(dev); + /* must be power of 2 */ sky2->tx_le = pci_alloc_consistent(hw->pdev, TX_RING_SIZE * @@ -1246,7 +1334,8 @@ GFP_KERNEL); if (!sky2->tx_ring) goto err_out; - sky2->tx_prod = sky2->tx_cons = 0; + + tx_init(sky2); sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES, &sky2->rx_le_map); @@ -1265,11 +1354,10 @@ /* Register is number of 4K blocks on internal RAM buffer. */ ramsize = sky2_read8(hw, B2_E_0) * 4; - printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize); - if (ramsize > 0) { u32 rxspace; + pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize); if (ramsize < 16) rxspace = ramsize / 2; else @@ -1285,6 +1373,10 @@ sky2_qset(hw, txqaddr[port]); + /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */ + if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0) + sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF); + /* Set almost empty threshold */ if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_U_A0) @@ -1380,27 +1472,32 @@ len = skb_headlen(skb); mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); - addr64 = high32(mapping); + addr64 = upper_32_bits(mapping); /* Send high bits if changed or crosses boundary */ - if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) { + if (addr64 != sky2->tx_addr64 || + upper_32_bits(mapping + len) != sky2->tx_addr64) { le = get_tx_le(sky2); le->addr = cpu_to_le32(addr64); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = high32(mapping + len); + sky2->tx_addr64 = upper_32_bits(mapping + len); } /* Check for TCP Segmentation Offload */ mss = skb_shinfo(skb)->gso_size; if (mss != 0) { - mss += tcp_optlen(skb); /* TCP options */ - mss += ip_hdrlen(skb) + sizeof(struct tcphdr); - mss += ETH_HLEN; - if (mss != sky2->tx_last_mss) { - le = get_tx_le(sky2); - le->addr = cpu_to_le32(mss); - le->opcode = OP_LRGLEN | HW_OWNER; + if (!(hw->flags & SKY2_HW_NEW_LE)) + mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); + + if (mss != sky2->tx_last_mss) { + le = get_tx_le(sky2); + le->addr = cpu_to_le32(mss); + + if (hw->flags & SKY2_HW_NEW_LE) + le->opcode = OP_MSS | HW_OWNER; + else + le->opcode = OP_LRGLEN | HW_OWNER; sky2->tx_last_mss = mss; } } @@ -1422,24 +1519,29 @@ /* Handle TCP checksum offload */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - const unsigned offset = skb_transport_offset(skb); - u32 tcpsum; - - tcpsum = offset << 16; /* sum start */ - tcpsum |= offset + skb->csum_offset; /* sum write */ - - ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; - if (ip_hdr(skb)->protocol == IPPROTO_UDP) - ctrl |= UDPTCP; - - if (tcpsum != sky2->tx_tcpsum) { - sky2->tx_tcpsum = tcpsum; - - le = get_tx_le(sky2); - le->addr = cpu_to_le32(tcpsum); - le->length = 0; /* initial checksum value */ - le->ctrl = 1; /* one packet */ - le->opcode = OP_TCPLISW | HW_OWNER; + /* On Yukon EX (some versions) encoding change. */ + if (hw->flags & SKY2_HW_AUTO_TX_SUM) + ctrl |= CALSUM; /* auto checksum */ + else { + const unsigned offset = skb_transport_offset(skb); + u32 tcpsum; + + tcpsum = offset << 16; /* sum start */ + tcpsum |= offset + skb->csum_offset; /* sum write */ + + ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + if (ip_hdr(skb)->protocol == IPPROTO_UDP) + ctrl |= UDPTCP; + + if (tcpsum != sky2->tx_tcpsum) { + sky2->tx_tcpsum = tcpsum; + + le = get_tx_le(sky2); + le->addr = cpu_to_le32(tcpsum); + le->length = 0; /* initial checksum value */ + le->ctrl = 1; /* one packet */ + le->opcode = OP_TCPLISW | HW_OWNER; + } } } @@ -1459,7 +1561,7 @@ mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - addr64 = high32(mapping); + addr64 = upper_32_bits(mapping); if (addr64 != sky2->tx_addr64) { le = get_tx_le(sky2); le->addr = cpu_to_le32(addr64); @@ -1529,13 +1631,13 @@ if (unlikely(netif_msg_tx_done(sky2))) printk(KERN_DEBUG "%s: tx done %u\n", dev->name, idx); + sky2->net_stats.tx_packets++; sky2->net_stats.tx_bytes += re->skb->len; dev_kfree_skb_any(re->skb); + sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); } - - le->opcode = 0; /* paranoia */ } sky2->tx_cons = idx; @@ -1573,7 +1675,6 @@ /* Stop more packets from being queued */ netif_stop_queue(dev); - netif_carrier_off(dev); /* Disable port IRQ */ imask = sky2_read32(hw, B0_IMSK); @@ -1625,6 +1726,8 @@ sky2_phy_power(hw, port, 0); + netif_carrier_off(dev); + /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); @@ -1653,11 +1756,15 @@ static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) { - if (!sky2_is_copper(hw)) + if (hw->flags & SKY2_HW_FIBRE_PHY) return SPEED_1000; - if (hw->chip_id == CHIP_ID_YUKON_FE) - return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; + if (!(hw->flags & SKY2_HW_GIGABIT)) { + if (aux & PHY_M_PS_SPEED_100) + return SPEED_100; + else + return SPEED_10; + } switch (aux & PHY_M_PS_SPEED_MSK) { case PHY_M_PS_SPEED_1000: @@ -1689,15 +1796,14 @@ gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); netif_carrier_on(sky2->netdev); - netif_wake_queue(sky2->netdev); + + mod_timer(&hw->watchdog_timer, jiffies + 1); /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); - if (hw->chip_id == CHIP_ID_YUKON_XL - || hw->chip_id == CHIP_ID_YUKON_EC_U - || hw->chip_id == CHIP_ID_YUKON_EX) { + if (hw->flags & SKY2_HW_NEWER_PHY) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ @@ -1741,7 +1847,6 @@ gma_write16(hw, port, GM_GP_CTRL, reg); netif_carrier_off(sky2->netdev); - netif_stop_queue(sky2->netdev); /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); @@ -1785,7 +1890,7 @@ /* Since the pause result bits seem to in different positions on * different chips. look at registers. */ - if (!sky2_is_copper(hw)) { + if (hw->flags & SKY2_HW_FIBRE_PHY) { /* Shift for bits in fiber PHY */ advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); @@ -1896,7 +2001,9 @@ if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; - if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE) + if (new_mtu > ETH_DATA_LEN && + (hw->chip_id == CHIP_ID_YUKON_FE || + hw->chip_id == CHIP_ID_YUKON_FE_P)) return -EINVAL; if (!netif_running(dev)) { @@ -1913,15 +2020,8 @@ synchronize_irq(hw->pdev->irq); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { - if (new_mtu > ETH_DATA_LEN) { - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_ENA | TX_STFW_DIS); - dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; - } else - sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), - TX_JUMBO_DIS | TX_STFW_ENA); - } + if (sky2_read8(hw, B2_E_0) == 0) + sky2_set_tx_stfwd(hw, port); ctl = gma_read16(hw, port, GM_GP_CTRL); gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); @@ -2019,8 +2119,6 @@ struct sk_buff *skb, *nskb; unsigned hdr_space = sky2->rx_data_size; - pr_debug(PFX "receive new length=%d\n", length); - /* Don't be tricky about reusing pages (yet) */ nskb = sky2_rx_alloc(sky2); if (unlikely(!nskb)) @@ -2050,6 +2148,13 @@ struct sky2_port *sky2 = netdev_priv(dev); struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; struct sk_buff *skb = NULL; + u16 count = (status & GMR_FS_LEN) >> 16; + +#ifdef SKY2_VLAN_TAG_USED + /* Account for vlan tag */ + if (sky2->vlgrp && (status & GMR_FS_VLAN)) + count -= VLAN_HLEN; +#endif if (unlikely(netif_msg_rx_status(sky2))) printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", @@ -2058,12 +2163,29 @@ sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next); + if (length < ETH_ZLEN || length > sky2->rx_data_size) + goto len_error; + + /* This chip has hardware problems that generates bogus status. + * So do only marginal checking and expect higher level protocols + * to handle crap frames. + */ + if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && + sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 && + length != count) + goto okay; + if (status & GMR_FS_ANY_ERR) goto error; if (!(status & GMR_FS_RX_OK)) goto resubmit; + /* if length reported by DMA does not match PHY, packet was truncated */ + if (length != count) + goto len_error; + +okay: if (length < copybreak) skb = receive_copy(sky2, re, length); else @@ -2073,6 +2195,15 @@ return skb; +len_error: + /* Truncation of overlength packets + causes PHY length to not match MAC length */ + ++sky2->net_stats.rx_length_errors; + if (netif_msg_rx_err(sky2) && net_ratelimit()) + pr_info(PFX "%s: rx length error: status %#x length %d\n", + dev->name, status, length); + goto resubmit; + error: ++sky2->net_stats.rx_errors; if (status & GMR_FS_RX_FF_OV) { @@ -2109,15 +2240,16 @@ /* Process status response ring */ static int sky2_status_intr(struct sky2_hw *hw, int to_do) { - struct sky2_port *sky2; int work_done = 0; - unsigned buf_write[2] = { 0, 0 }; + unsigned rx[2] = { 0, 0 }; u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); rmb(); while (hw->st_idx != hwidx) { + struct sky2_port *sky2; struct sky2_status_le *le = hw->st_le + hw->st_idx; + unsigned port = le->css & CSS_LINK_BIT; struct net_device *dev; struct sk_buff *skb; u32 status; @@ -2125,19 +2257,28 @@ hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); - BUG_ON(le->link >= 2); - dev = hw->dev[le->link]; - + dev = hw->dev[port]; sky2 = netdev_priv(dev); length = le16_to_cpu(le->length); status = le32_to_cpu(le->status); switch (le->opcode & ~HW_OWNER) { case OP_RXSTAT: + ++rx[port]; skb = sky2_receive(dev, length, status); if (unlikely(!skb)) { sky2->net_stats.rx_dropped++; - goto force_update; + break; + } + + /* This chip reports checksum status differently */ + if (hw->flags & SKY2_HW_NEW_LE) { + if (sky2->rx_csum && + (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && + (le->css & CSS_TCPUDPCSOK)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; } skb->protocol = eth_type_trans(skb, dev); @@ -2154,13 +2295,6 @@ #endif netif_receive_skb(skb); - /* Update receiver after 16 frames */ - if (++buf_write[le->link] == RX_BUF_WRITE) { -force_update: - sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put); - buf_write[le->link] = 0; - } - /* Stop after net poll weight */ if (++work_done >= to_do) goto exit_loop; @@ -2179,6 +2313,15 @@ if (!sky2->rx_csum) break; + /* If this happens then driver assuming wrong format */ + if (unlikely(hw->flags & SKY2_HW_NEW_LE)) { + if (net_ratelimit()) + printk(KERN_NOTICE "%s: unexpected" + " checksum status\n", + dev->name); + break; + } + /* Both checksum counters are programmed to start at * the same offset, so unless there is a problem they * should match. This failure is an early indication that @@ -2194,7 +2337,7 @@ dev->name, status); sky2->rx_csum = 0; sky2_write32(sky2->hw, - Q_ADDR(rxqaddr[le->link], Q_CSR), + Q_ADDR(rxqaddr[port], Q_CSR), BMU_DIS_RX_CHKSUM); } break; @@ -2213,24 +2356,18 @@ if (net_ratelimit()) printk(KERN_WARNING PFX "unknown status opcode 0x%x\n", le->opcode); - goto exit_loop; } } /* Fully processed status ring so clear irq */ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); - mmiowb(); exit_loop: - if (buf_write[0]) { - sky2 = netdev_priv(hw->dev[0]); - sky2_put_idx(hw, Q_R1, sky2->rx_put); - } + if (rx[0]) + sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1); - if (buf_write[1]) { - sky2 = netdev_priv(hw->dev[1]); - sky2_put_idx(hw, Q_R2, sky2->rx_put); - } + if (rx[1]) + sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2); return work_done; } @@ -2375,25 +2512,72 @@ sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); } -/* If idle then force a fake soft NAPI poll once a second - * to work around cases where sharing an edge triggered interrupt. - */ -static inline void sky2_idle_start(struct sky2_hw *hw) +static int sky2_rx_hung(struct net_device *dev) { - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); + struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + unsigned rxq = rxqaddr[port]; + u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP)); + u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV)); + u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP)); + u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL)); + + /* If idle and MAC or PCI is stuck */ + if (sky2->check.last == dev->last_rx && + ((mac_rp == sky2->check.mac_rp && + mac_lev != 0 && mac_lev >= sky2->check.mac_lev) || + /* Check if the PCI RX hang */ + (fifo_rp == sky2->check.fifo_rp && + fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) { + printk(KERN_DEBUG PFX "%s: hung mac %d:%d fifo %d (%d:%d)\n", + dev->name, mac_lev, mac_rp, fifo_lev, fifo_rp, + sky2_read8(hw, Q_ADDR(rxq, Q_WP))); + return 1; + } else { + sky2->check.last = dev->last_rx; + sky2->check.mac_rp = mac_rp; + sky2->check.mac_lev = mac_lev; + sky2->check.fifo_rp = fifo_rp; + sky2->check.fifo_lev = fifo_lev; + return 0; + } } -static void sky2_idle(unsigned long arg) +static void sky2_watchdog(unsigned long arg) { struct sky2_hw *hw = (struct sky2_hw *) arg; - struct net_device *dev = hw->dev[0]; + struct net_device *dev; + + /* Check for lost IRQ once a second */ + if (sky2_read32(hw, B0_ISRC)) { + dev = hw->dev[0]; + if (__netif_rx_schedule_prep(dev)) + __netif_rx_schedule(dev); + } else { + int i, active = 0; - if (__netif_rx_schedule_prep(dev)) - __netif_rx_schedule(dev); + for (i = 0; i < hw->ports; i++) { + dev = hw->dev[i]; + if (!netif_running(dev)) + continue; + ++active; + + /* For chips with Rx FIFO, check if stuck */ + if ((hw->flags & SKY2_HW_FIFO_HANG_CHECK) && + sky2_rx_hung(dev)) { + pr_info(PFX "%s: receiver hang detected\n", + dev->name); + schedule_work(&hw->restart_work); + return; + } + } + + if (active == 0) + return; + } - mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); + mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); } /* Hardware/software error handling */ @@ -2427,8 +2611,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) { struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; - int work_limit = min(dev0->quota, *budget); - int work_done = 0; + int work_done; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); if (unlikely(status & Y2_IS_ERROR)) @@ -2440,18 +2623,25 @@ if (status & Y2_IS_IRQ_PHY2) sky2_phy_intr(hw, 1); - work_done = sky2_status_intr(hw, work_limit); - if (work_done < work_limit) { - netif_rx_complete(dev0); + work_done = sky2_status_intr(hw, min(dev0->quota, *budget)); + *budget -= work_done; + dev0->quota -= work_done; - /* end of interrupt, re-enables also acts as I/O synchronization */ - sky2_read32(hw, B0_Y2_SP_LISR); - return 0; - } else { - *budget -= work_done; - dev0->quota -= work_done; + /* More work? */ + if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)) return 1; + + /* Bug/Errata workaround? + * Need to kick the TX irq moderation timer. + */ + if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); } + netif_rx_complete(dev0); + + sky2_read32(hw, B0_Y2_SP_LISR); + return 0; } static irqreturn_t sky2_intr(int irq, void *dev_id) @@ -2484,17 +2674,25 @@ #endif /* Chip internal frequency for clock calculations */ -static inline u32 sky2_mhz(const struct sky2_hw *hw) +static u32 sky2_mhz(const struct sky2_hw *hw) { switch (hw->chip_id) { case CHIP_ID_YUKON_EC: case CHIP_ID_YUKON_EC_U: case CHIP_ID_YUKON_EX: - return 125; /* 125 Mhz */ + return 125; + case CHIP_ID_YUKON_FE: - return 100; /* 100 Mhz */ - default: /* YUKON_XL */ - return 156; /* 156 Mhz */ + return 100; + + case CHIP_ID_YUKON_FE_P: + return 50; + + case CHIP_ID_YUKON_XL: + return 156; + + default: + BUG(); } } @@ -2513,34 +2711,69 @@ { u8 t8; + /* Enable all clocks */ + sky2_pci_write32(hw, PCI_DEV_REG3, 0); + sky2_write8(hw, B0_CTST, CS_RST_CLR); hw->chip_id = sky2_read8(hw, B2_CHIP_ID); - if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { - dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", - hw->chip_id); - return -EOPNOTSUPP; - } + hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; - if (hw->chip_id == CHIP_ID_YUKON_EX) - dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" - "Please report success or failure to \n"); + switch(hw->chip_id) { + case CHIP_ID_YUKON_XL: + hw->flags = SKY2_HW_GIGABIT + | SKY2_HW_NEWER_PHY; + if (hw->chip_rev < 3) + hw->flags |= SKY2_HW_FIFO_HANG_CHECK; - /* Make sure and enable all clocks */ - if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) - sky2_pci_write32(hw, PCI_DEV_REG3, 0); + break; - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; + case CHIP_ID_YUKON_EC_U: + hw->flags = SKY2_HW_GIGABIT + | SKY2_HW_NEWER_PHY + | SKY2_HW_ADV_POWER_CTL; + break; - /* This rev is really old, and requires untested workarounds */ - if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { - dev_err(&hw->pdev->dev, "unsupported revision Yukon-%s (0x%x) rev %d\n", - yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], - hw->chip_id, hw->chip_rev); + case CHIP_ID_YUKON_EX: + hw->flags = SKY2_HW_GIGABIT + | SKY2_HW_NEWER_PHY + | SKY2_HW_NEW_LE + | SKY2_HW_ADV_POWER_CTL; + + /* New transmit checksum */ + if (hw->chip_rev != CHIP_REV_YU_EX_B0) + hw->flags |= SKY2_HW_AUTO_TX_SUM; + break; + + case CHIP_ID_YUKON_EC: + /* This rev is really old, and requires untested workarounds */ + if (hw->chip_rev == CHIP_REV_YU_EC_A1) { + dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); + return -EOPNOTSUPP; + } + hw->flags = SKY2_HW_GIGABIT | SKY2_HW_FIFO_HANG_CHECK; + break; + + case CHIP_ID_YUKON_FE: + break; + + case CHIP_ID_YUKON_FE_P: + hw->flags = SKY2_HW_NEWER_PHY + | SKY2_HW_NEW_LE + | SKY2_HW_AUTO_TX_SUM + | SKY2_HW_ADV_POWER_CTL; + break; + default: + dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", + hw->chip_id); return -EOPNOTSUPP; } hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); + if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') + hw->flags |= SKY2_HW_FIBRE_PHY; + + hw->ports = 1; t8 = sky2_read8(hw, B2_Y2_HW_RES); if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { @@ -2589,6 +2822,11 @@ for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + + if (hw->chip_id == CHIP_ID_YUKON_EX) + sky2_write16(hw, SK_REG(i, GMAC_CTRL), + GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON + | GMC_BYP_RETR_ON); } sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); @@ -2675,10 +2913,6 @@ struct net_device *dev; int i, err; - dev_dbg(&hw->pdev->dev, "restarting\n"); - - del_timer_sync(&hw->idle_timer); - rtnl_lock(); sky2_write32(hw, B0_IMSK, 0); sky2_read32(hw, B0_IMSK); @@ -2707,8 +2941,6 @@ } } - sky2_idle_start(hw); - rtnl_unlock(); } @@ -2735,7 +2967,9 @@ sky2->wol = wol->wolopts; - if (hw->chip_id == CHIP_ID_YUKON_EC_U) + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_FE_P) sky2_write32(hw, B0_CTST, sky2->wol ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); @@ -2753,7 +2987,7 @@ | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP; - if (hw->chip_id != CHIP_ID_YUKON_FE) + if (hw->flags & SKY2_HW_GIGABIT) modes |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; return modes; @@ -2773,13 +3007,6 @@ ecmd->supported = sky2_supported_modes(hw); ecmd->phy_address = PHY_ADDR_MARV; if (sky2_is_copper(hw)) { - ecmd->supported = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full - | SUPPORTED_Autoneg | SUPPORTED_TP; ecmd->port = PORT_TP; ecmd->speed = sky2->speed; } else { @@ -2846,8 +3073,10 @@ sky2->autoneg = ecmd->autoneg; sky2->advertising = ecmd->advertising; - if (netif_running(dev)) + if (netif_running(dev)) { sky2_phy_reinit(sky2); + sky2_set_multicast(dev); + } return 0; } @@ -2940,6 +3169,7 @@ return -EINVAL; sky2_phy_reinit(sky2); + sky2_set_multicast(dev); return 0; } @@ -3330,7 +3560,7 @@ /* * Returns copy of control register region - * Note: access to the RAM address register set will cause timeouts. + * Note: ethtool_get_regs always provides full size (16k) buffer */ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) @@ -3338,15 +3568,19 @@ const struct sky2_port *sky2 = netdev_priv(dev); const void __iomem *io = sky2->hw->regs; - BUG_ON(regs->len < B3_RI_WTO_R1); regs->version = 1; memset(p, 0, regs->len); memcpy_fromio(p, io, B3_RAM_ADDR); - memcpy_fromio(p + B3_RI_WTO_R1, - io + B3_RI_WTO_R1, - regs->len - B3_RI_WTO_R1); + /* skip diagnostic ram region */ + memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1); + + /* copy GMAC registers */ + memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000); + if (sky2->hw->ports > 1) + memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000); + } /* In order to do Jumbo packets on these chips, need to turn off the @@ -3357,9 +3591,7 @@ const struct sky2_port *sky2 = netdev_priv(dev); const struct sky2_hw *hw = sky2->hw; - return dev->mtu > ETH_DATA_LEN && - (hw->chip_id == CHIP_ID_YUKON_EX - || hw->chip_id == CHIP_ID_YUKON_EC_U); + return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; } static int sky2_set_tx_csum(struct net_device *dev, u32 data) @@ -3379,39 +3611,314 @@ return ethtool_op_set_tso(dev, data); } +static int sky2_get_eeprom_len(struct net_device *dev) +{ + struct sky2_port *sky2 = netdev_priv(dev); + u16 reg2; + + reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2); + return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8); +} + +static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset) +{ + sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset); + + while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F)) + cpu_relax(); + return sky2_pci_read32(hw, cap + PCI_VPD_DATA); +} + +static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val) +{ + sky2_pci_write32(hw, cap + PCI_VPD_DATA, val); + sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F); + do { + cpu_relax(); + } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F); +} + +static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct sky2_port *sky2 = netdev_priv(dev); + int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD); + int length = eeprom->len; + u16 offset = eeprom->offset; + + if (!cap) + return -EINVAL; + + eeprom->magic = SKY2_EEPROM_MAGIC; + + while (length > 0) { + u32 val = sky2_vpd_read(sky2->hw, cap, offset); + int n = min_t(int, length, sizeof(val)); + + memcpy(data, &val, n); + length -= n; + data += n; + offset += n; + } + return 0; +} + +static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct sky2_port *sky2 = netdev_priv(dev); + int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD); + int length = eeprom->len; + u16 offset = eeprom->offset; + + if (!cap) + return -EINVAL; + + if (eeprom->magic != SKY2_EEPROM_MAGIC) + return -EINVAL; + + while (length > 0) { + u32 val; + int n = min_t(int, length, sizeof(val)); + + if (n < sizeof(val)) + val = sky2_vpd_read(sky2->hw, cap, offset); + memcpy(&val, data, n); + + sky2_vpd_write(sky2->hw, cap, offset, val); + + length -= n; + data += n; + offset += n; + } + return 0; +} + + static const struct ethtool_ops sky2_ethtool_ops = { - .get_settings = sky2_get_settings, - .set_settings = sky2_set_settings, - .get_drvinfo = sky2_get_drvinfo, - .get_wol = sky2_get_wol, - .set_wol = sky2_set_wol, - .get_msglevel = sky2_get_msglevel, - .set_msglevel = sky2_set_msglevel, - .nway_reset = sky2_nway_reset, - .get_regs_len = sky2_get_regs_len, - .get_regs = sky2_get_regs, - .get_link = ethtool_op_get_link, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = sky2_set_tx_csum, - .get_tso = ethtool_op_get_tso, - .set_tso = sky2_set_tso, - .get_rx_csum = sky2_get_rx_csum, - .set_rx_csum = sky2_set_rx_csum, - .get_strings = sky2_get_strings, - .get_coalesce = sky2_get_coalesce, - .set_coalesce = sky2_set_coalesce, - .get_ringparam = sky2_get_ringparam, - .set_ringparam = sky2_set_ringparam, + .get_settings = sky2_get_settings, + .set_settings = sky2_set_settings, + .get_drvinfo = sky2_get_drvinfo, + .get_wol = sky2_get_wol, + .set_wol = sky2_set_wol, + .get_msglevel = sky2_get_msglevel, + .set_msglevel = sky2_set_msglevel, + .nway_reset = sky2_nway_reset, + .get_regs_len = sky2_get_regs_len, + .get_regs = sky2_get_regs, + .get_link = ethtool_op_get_link, + .get_eeprom_len = sky2_get_eeprom_len, + .get_eeprom = sky2_get_eeprom, + .set_eeprom = sky2_set_eeprom, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = sky2_set_tx_csum, + .get_tso = ethtool_op_get_tso, + .set_tso = sky2_set_tso, + .get_rx_csum = sky2_get_rx_csum, + .set_rx_csum = sky2_set_rx_csum, + .get_strings = sky2_get_strings, + .get_coalesce = sky2_get_coalesce, + .set_coalesce = sky2_set_coalesce, + .get_ringparam = sky2_get_ringparam, + .set_ringparam = sky2_set_ringparam, .get_pauseparam = sky2_get_pauseparam, .set_pauseparam = sky2_set_pauseparam, - .phys_id = sky2_phys_id, + .phys_id = sky2_phys_id, .get_stats_count = sky2_get_stats_count, .get_ethtool_stats = sky2_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; +#ifdef CONFIG_SKY2_DEBUG + +static struct dentry *sky2_debug; + +static int sky2_debug_show(struct seq_file *seq, void *v) +{ + struct net_device *dev = seq->private; + const struct sky2_port *sky2 = netdev_priv(dev); + const struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + unsigned idx, last; + int sop; + + if (!netif_running(dev)) + return -ENETDOWN; + + seq_printf(seq, "IRQ src=%x mask=%x control=%x\n", + sky2_read32(hw, B0_ISRC), + sky2_read32(hw, B0_IMSK), + sky2_read32(hw, B0_Y2_SP_ICR)); + + netif_poll_disable(hw->dev[0]); + last = sky2_read16(hw, STAT_PUT_IDX); + + if (hw->st_idx == last) + seq_puts(seq, "Status ring (empty)\n"); + else { + seq_puts(seq, "Status ring\n"); + for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE; + idx = RING_NEXT(idx, STATUS_RING_SIZE)) { + const struct sky2_status_le *le = hw->st_le + idx; + seq_printf(seq, "[%d] %#x %d %#x\n", + idx, le->opcode, le->length, le->status); + } + seq_puts(seq, "\n"); + } + + seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n", + sky2->tx_cons, sky2->tx_prod, + sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX), + sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE))); + + /* Dump contents of tx ring */ + sop = 1; + for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE; + idx = RING_NEXT(idx, TX_RING_SIZE)) { + const struct sky2_tx_le *le = sky2->tx_le + idx; + u32 a = le32_to_cpu(le->addr); + + if (sop) + seq_printf(seq, "%u:", idx); + sop = 0; + + switch(le->opcode & ~HW_OWNER) { + case OP_ADDR64: + seq_printf(seq, " %#x:", a); + break; + case OP_LRGLEN: + seq_printf(seq, " mtu=%d", a); + break; + case OP_VLAN: + seq_printf(seq, " vlan=%d", be16_to_cpu(le->length)); + break; + case OP_TCPLISW: + seq_printf(seq, " csum=%#x", a); + break; + case OP_LARGESEND: + seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length)); + break; + case OP_PACKET: + seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length)); + break; + case OP_BUFFER: + seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length)); + break; + default: + seq_printf(seq, " op=%#x,%#x(%d)", le->opcode, + a, le16_to_cpu(le->length)); + } + + if (le->ctrl & EOP) { + seq_putc(seq, '\n'); + sop = 1; + } + } + + seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n", + sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)), + last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), + sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); + + netif_poll_enable(hw->dev[0]); + return 0; +} + +static int sky2_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, sky2_debug_show, inode->i_private); +} + +static const struct file_operations sky2_debug_fops = { + .owner = THIS_MODULE, + .open = sky2_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * Use network device events to create/remove/rename + * debugfs file entries + */ +static int sky2_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + + if (dev->open == sky2_up) { + struct sky2_port *sky2 = netdev_priv(dev); + + switch(event) { + case NETDEV_CHANGENAME: + if (!netif_running(dev)) + break; + /* fallthrough */ + case NETDEV_DOWN: + case NETDEV_GOING_DOWN: + if (sky2->debugfs) { + printk(KERN_DEBUG PFX "%s: remove debugfs\n", + dev->name); + debugfs_remove(sky2->debugfs); + sky2->debugfs = NULL; + } + + if (event != NETDEV_CHANGENAME) + break; + /* fallthrough for changename */ + case NETDEV_UP: + if (sky2_debug) { + struct dentry *d; + d = debugfs_create_file(dev->name, S_IRUGO, + sky2_debug, dev, + &sky2_debug_fops); + if (d == NULL || IS_ERR(d)) + printk(KERN_INFO PFX + "%s: debugfs create failed\n", + dev->name); + else + sky2->debugfs = d; + } + break; + } + } + + return NOTIFY_DONE; +} + +static struct notifier_block sky2_notifier = { + .notifier_call = sky2_device_event, +}; + + +static __init void sky2_debug_init(void) +{ + struct dentry *ent; + + ent = debugfs_create_dir("sky2", NULL); + if (!ent || IS_ERR(ent)) + return; + + sky2_debug = ent; + register_netdevice_notifier(&sky2_notifier); +} + +static __exit void sky2_debug_cleanup(void) +{ + if (sky2_debug) { + unregister_netdevice_notifier(&sky2_notifier); + debugfs_remove(sky2_debug); + sky2_debug = NULL; + } +} + +#else +#define sky2_debug_init() +#define sky2_debug_cleanup() +#endif + + /* Initialize network device */ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, @@ -3478,18 +3985,18 @@ dev->features |= NETIF_F_HIGHDMA; #ifdef SKY2_VLAN_TAG_USED - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register = sky2_vlan_rx_register; + /* The workaround for FE+ status conflicts with VLAN tag detection. */ + if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && + sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) { + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_rx_register = sky2_vlan_rx_register; + } #endif /* read the mac address */ memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - /* device is off until link detection */ - netif_carrier_off(dev); - netif_stop_queue(dev); - return dev; } @@ -3514,7 +4021,7 @@ return IRQ_NONE; if (status & Y2_IS_IRQ_SW) { - hw->msi = 1; + hw->flags |= SKY2_HW_USE_MSI; wake_up(&hw->msi_wait); sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); } @@ -3542,9 +4049,9 @@ sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); sky2_read8(hw, B0_CTST); - wait_event_timeout(hw->msi_wait, hw->msi, HZ/10); + wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10); - if (!hw->msi) { + if (!(hw->flags & SKY2_HW_USE_MSI)) { /* MSI test failed, go back to INTx mode */ dev_info(&pdev->dev, "No interrupt generated using MSI, " "switching to INTx mode.\n"); @@ -3677,7 +4184,8 @@ goto err_out_free_netdev; } - err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED, + err = request_irq(pdev->irq, sky2_intr, + (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED, dev->name, hw); if (err) { dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); @@ -3702,17 +4210,15 @@ sky2_show_addr(dev1); } - setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); + setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw); INIT_WORK(&hw->restart_work, sky2_restart); - sky2_idle_start(hw); - pci_set_drvdata(pdev, hw); return 0; err_out_unregister: - if (hw->msi) + if (hw->flags & SKY2_HW_USE_MSI) pci_disable_msi(pdev); unregister_netdev(dev); err_out_free_netdev: @@ -3741,7 +4247,7 @@ if (!hw) return; - del_timer_sync(&hw->idle_timer); + del_timer_sync(&hw->watchdog_timer); flush_scheduled_work(); @@ -3761,7 +4267,7 @@ sky2_read8(hw, B0_CTST); free_irq(pdev->irq, hw); - if (hw->msi) + if (hw->flags & SKY2_HW_USE_MSI) pci_disable_msi(pdev); pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); pci_release_regions(pdev); @@ -3785,7 +4291,6 @@ if (!hw) return 0; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { @@ -3830,7 +4335,9 @@ pci_enable_wake(pdev, PCI_D0, 0); /* Re-enable all clocks */ - if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) + if (hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_FE_P) sky2_pci_write32(hw, PCI_DEV_REG3, 0); sky2_reset(hw); @@ -3847,11 +4354,13 @@ dev_close(dev); goto out; } + + sky2_set_multicast(dev); } } netif_poll_enable(hw->dev[0]); - sky2_idle_start(hw); + return 0; out: dev_err(&pdev->dev, "resume failed (%d)\n", err); @@ -3868,7 +4377,6 @@ if (!hw) return; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { @@ -3906,12 +4414,14 @@ static int __init sky2_init_module(void) { + sky2_debug_init(); return pci_register_driver(&sky2_driver); } static void __exit sky2_cleanup_module(void) { pci_unregister_driver(&sky2_driver); + sky2_debug_cleanup(); } module_init(sky2_init_module); --- linux-source-2.6.22-2.6.22.orig/drivers/net/bonding/bond_main.c +++ linux-source-2.6.22-2.6.22/drivers/net/bonding/bond_main.c @@ -1233,43 +1233,31 @@ return 0; } -#define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) +#define BOND_VLAN_FEATURES \ + (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \ + NETIF_F_HW_VLAN_FILTER) /* * Compute the common dev->feature set available to all slaves. Some - * feature bits are managed elsewhere, so preserve feature bits set on - * master device that are not part of the examined set. + * feature bits are managed elsewhere, so preserve those feature bits + * on the master device. */ static int bond_compute_features(struct bonding *bond) { - unsigned long features = BOND_INTERSECT_FEATURES; struct slave *slave; struct net_device *bond_dev = bond->dev; + unsigned long features = bond_dev->features & ~BOND_VLAN_FEATURES; unsigned short max_hard_header_len = ETH_HLEN; int i; bond_for_each_slave(bond, slave, i) { - features &= (slave->dev->features & BOND_INTERSECT_FEATURES); + features = netdev_compute_features(features, + slave->dev->features); if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; } - if ((features & NETIF_F_SG) && - !(features & NETIF_F_ALL_CSUM)) - features &= ~NETIF_F_SG; - - /* - * features will include NETIF_F_TSO (NETIF_F_UFO) iff all - * slave devices support NETIF_F_TSO (NETIF_F_UFO), which - * implies that all slaves also support scatter-gather - * (NETIF_F_SG), which implies that features also includes - * NETIF_F_SG. So no need to check whether we have an - * illegal combination of NETIF_F_{TSO,UFO} and - * !NETIF_F_SG - */ - - features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); + features |= (bond_dev->features & BOND_VLAN_FEATURES); bond_dev->features = features; bond_dev->hard_header_len = max_hard_header_len; --- linux-source-2.6.22-2.6.22.orig/drivers/net/sky2.h +++ linux-source-2.6.22-2.6.22/drivers/net/sky2.h @@ -14,6 +14,8 @@ PCI_DEV_REG3 = 0x80, PCI_DEV_REG4 = 0x84, PCI_DEV_REG5 = 0x88, + PCI_CFG_REG_0 = 0x90, + PCI_CFG_REG_1 = 0x94, }; enum { @@ -28,6 +30,7 @@ enum pci_dev_reg_1 { PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ PCI_Y2_DLL_DIS = 1<<30, /* Disable PCI DLL (YUKON-2) */ + PCI_SW_PWR_ON_RST= 1<<30, /* SW Power on Reset (Yukon-EX) */ PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */ PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */ PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */ @@ -67,6 +70,80 @@ | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY, }; +/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */ +enum pci_dev_reg_5 { + /* Bit 31..27: for A3 & later */ + P_CTL_DIV_CORE_CLK_ENA = 1<<31, /* Divide Core Clock Enable */ + P_CTL_SRESET_VMAIN_AV = 1<<30, /* Soft Reset for Vmain_av De-Glitch */ + P_CTL_BYPASS_VMAIN_AV = 1<<29, /* Bypass En. for Vmain_av De-Glitch */ + P_CTL_TIM_VMAIN_AV_MSK = 3<<27, /* Bit 28..27: Timer Vmain_av Mask */ + /* Bit 26..16: Release Clock on Event */ + P_REL_PCIE_RST_DE_ASS = 1<<26, /* PCIe Reset De-Asserted */ + P_REL_GPHY_REC_PACKET = 1<<25, /* GPHY Received Packet */ + P_REL_INT_FIFO_N_EMPTY = 1<<24, /* Internal FIFO Not Empty */ + P_REL_MAIN_PWR_AVAIL = 1<<23, /* Main Power Available */ + P_REL_CLKRUN_REQ_REL = 1<<22, /* CLKRUN Request Release */ + P_REL_PCIE_RESET_ASS = 1<<21, /* PCIe Reset Asserted */ + P_REL_PME_ASSERTED = 1<<20, /* PME Asserted */ + P_REL_PCIE_EXIT_L1_ST = 1<<19, /* PCIe Exit L1 State */ + P_REL_LOADER_NOT_FIN = 1<<18, /* EPROM Loader Not Finished */ + P_REL_PCIE_RX_EX_IDLE = 1<<17, /* PCIe Rx Exit Electrical Idle State */ + P_REL_GPHY_LINK_UP = 1<<16, /* GPHY Link Up */ + + /* Bit 10.. 0: Mask for Gate Clock */ + P_GAT_PCIE_RST_ASSERTED = 1<<10,/* PCIe Reset Asserted */ + P_GAT_GPHY_N_REC_PACKET = 1<<9, /* GPHY Not Received Packet */ + P_GAT_INT_FIFO_EMPTY = 1<<8, /* Internal FIFO Empty */ + P_GAT_MAIN_PWR_N_AVAIL = 1<<7, /* Main Power Not Available */ + P_GAT_CLKRUN_REQ_REL = 1<<6, /* CLKRUN Not Requested */ + P_GAT_PCIE_RESET_ASS = 1<<5, /* PCIe Reset Asserted */ + P_GAT_PME_DE_ASSERTED = 1<<4, /* PME De-Asserted */ + P_GAT_PCIE_ENTER_L1_ST = 1<<3, /* PCIe Enter L1 State */ + P_GAT_LOADER_FINISHED = 1<<2, /* EPROM Loader Finished */ + P_GAT_PCIE_RX_EL_IDLE = 1<<1, /* PCIe Rx Electrical Idle State */ + P_GAT_GPHY_LINK_DOWN = 1<<0, /* GPHY Link Down */ + + PCIE_OUR5_EVENT_CLK_D3_SET = P_REL_GPHY_REC_PACKET | + P_REL_INT_FIFO_N_EMPTY | + P_REL_PCIE_EXIT_L1_ST | + P_REL_PCIE_RX_EX_IDLE | + P_GAT_GPHY_N_REC_PACKET | + P_GAT_INT_FIFO_EMPTY | + P_GAT_PCIE_ENTER_L1_ST | + P_GAT_PCIE_RX_EL_IDLE, +}; + +#/* PCI_CFG_REG_1 32 bit Config Register 1 (Yukon-Ext only) */ +enum pci_cfg_reg1 { + P_CF1_DIS_REL_EVT_RST = 1<<24, /* Dis. Rel. Event during PCIE reset */ + /* Bit 23..21: Release Clock on Event */ + P_CF1_REL_LDR_NOT_FIN = 1<<23, /* EEPROM Loader Not Finished */ + P_CF1_REL_VMAIN_AVLBL = 1<<22, /* Vmain available */ + P_CF1_REL_PCIE_RESET = 1<<21, /* PCI-E reset */ + /* Bit 20..18: Gate Clock on Event */ + P_CF1_GAT_LDR_NOT_FIN = 1<<20, /* EEPROM Loader Finished */ + P_CF1_GAT_PCIE_RX_IDLE = 1<<19, /* PCI-E Rx Electrical idle */ + P_CF1_GAT_PCIE_RESET = 1<<18, /* PCI-E Reset */ + P_CF1_PRST_PHY_CLKREQ = 1<<17, /* Enable PCI-E rst & PM2PHY gen. CLKREQ */ + P_CF1_PCIE_RST_CLKREQ = 1<<16, /* Enable PCI-E rst generate CLKREQ */ + + P_CF1_ENA_CFG_LDR_DONE = 1<<8, /* Enable core level Config loader done */ + + P_CF1_ENA_TXBMU_RD_IDLE = 1<<1, /* Enable TX BMU Read IDLE for ASPM */ + P_CF1_ENA_TXBMU_WR_IDLE = 1<<0, /* Enable TX BMU Write IDLE for ASPM */ + + PCIE_CFG1_EVENT_CLK_D3_SET = P_CF1_DIS_REL_EVT_RST | + P_CF1_REL_LDR_NOT_FIN | + P_CF1_REL_VMAIN_AVLBL | + P_CF1_REL_PCIE_RESET | + P_CF1_GAT_LDR_NOT_FIN | + P_CF1_GAT_PCIE_RESET | + P_CF1_PRST_PHY_CLKREQ | + P_CF1_ENA_CFG_LDR_DONE | + P_CF1_ENA_TXBMU_RD_IDLE | + P_CF1_ENA_TXBMU_WR_IDLE, +}; + #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \ @@ -364,6 +441,20 @@ TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */ }; +/* B2_GPIO */ +enum { + GLB_GPIO_CLK_DEB_ENA = 1<<31, /* Clock Debug Enable */ + GLB_GPIO_CLK_DBG_MSK = 0xf<<26, /* Clock Debug */ + + GLB_GPIO_INT_RST_D3_DIS = 1<<15, /* Disable Internal Reset After D3 to D0 */ + GLB_GPIO_LED_PAD_SPEED_UP = 1<<14, /* LED PAD Speed Up */ + GLB_GPIO_STAT_RACE_DIS = 1<<13, /* Status Race Disable */ + GLB_GPIO_TEST_SEL_MSK = 3<<11, /* Testmode Select */ + GLB_GPIO_TEST_SEL_BASE = 1<<11, + GLB_GPIO_RAND_ENA = 1<<10, /* Random Enable */ + GLB_GPIO_RAND_BIT_1 = 1<<9, /* Random Bit 1 */ +}; + /* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ enum { CFG_CHIP_R_MSK = 0xf<<4, /* Bit 7.. 4: Chip Revision */ @@ -379,19 +470,30 @@ CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ - + CHIP_ID_YUKON_FE_P = 0xb8, /* Chip ID for YUKON-2 FE+ */ +}; +enum yukon_ec_rev { CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ - +}; +enum yukon_ec_u_rev { CHIP_REV_YU_EC_U_A0 = 1, CHIP_REV_YU_EC_U_A1 = 2, CHIP_REV_YU_EC_U_B0 = 3, - +}; +enum yukon_fe_rev { CHIP_REV_YU_FE_A1 = 1, CHIP_REV_YU_FE_A2 = 2, - }; +enum yukon_fe_p_rev { + CHIP_REV_YU_FE2_A0 = 0, +}; +enum yukon_ex_rev { + CHIP_REV_YU_EX_A0 = 1, + CHIP_REV_YU_EX_B0 = 2, +}; + /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ enum { @@ -515,23 +617,15 @@ enum { B8_Q_REGS = 0x0400, /* base of Queue registers */ Q_D = 0x00, /* 8*32 bit Current Descriptor */ - Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ - Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ + Q_VLAN = 0x20, /* 16 bit Current VLAN Tag */ + Q_DONE = 0x24, /* 16 bit Done Index */ Q_AC_L = 0x28, /* 32 bit Current Address Counter Low dWord */ Q_AC_H = 0x2c, /* 32 bit Current Address Counter High dWord */ Q_BC = 0x30, /* 32 bit Current Byte Counter */ Q_CSR = 0x34, /* 32 bit BMU Control/Status Register */ - Q_F = 0x38, /* 32 bit Flag Register */ - Q_T1 = 0x3c, /* 32 bit Test Register 1 */ - Q_T1_TR = 0x3c, /* 8 bit Test Register 1 Transfer SM */ - Q_T1_WR = 0x3d, /* 8 bit Test Register 1 Write Descriptor SM */ - Q_T1_RD = 0x3e, /* 8 bit Test Register 1 Read Descriptor SM */ - Q_T1_SV = 0x3f, /* 8 bit Test Register 1 Supervisor SM */ - Q_T2 = 0x40, /* 32 bit Test Register 2 */ - Q_T3 = 0x44, /* 32 bit Test Register 3 */ + Q_TEST = 0x38, /* 32 bit Test/Control Register */ /* Yukon-2 */ - Q_DONE = 0x24, /* 16 bit Done Index (Yukon-2 only) */ Q_WM = 0x40, /* 16 bit FIFO Watermark */ Q_AL = 0x42, /* 8 bit FIFO Alignment */ Q_RSP = 0x44, /* 16 bit FIFO Read Shadow Pointer */ @@ -545,15 +639,16 @@ }; #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs)) -/* Q_F 32 bit Flag Register */ +/* Q_TEST 32 bit Test Register */ enum { - F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */ - F_EMPTY = 1<<27, /* Tx FIFO: empty flag */ - F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */ - F_WM_REACHED = 1<<25, /* Watermark reached */ + /* Transmit */ + F_TX_CHK_AUTO_OFF = 1<<31, /* Tx checksum auto calc off (Yukon EX) */ + F_TX_CHK_AUTO_ON = 1<<30, /* Tx checksum auto calc off (Yukon EX) */ + + /* Receive */ F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */ - F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */ - F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */ + + /* Hardware testbits not used */ }; /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/ @@ -1579,7 +1674,7 @@ /* Receive Frame Status Encoding */ enum { - GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ + GMR_FS_LEN = 0x7fff<<16, /* Bit 30..16: Rx Frame Length */ GMR_FS_VLAN = 1<<13, /* VLAN Packet */ GMR_FS_JABBER = 1<<12, /* Jabber Packet */ GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ @@ -1608,6 +1703,16 @@ RX_VLAN_STRIP_ON = 1<<25, /* enable VLAN stripping */ RX_VLAN_STRIP_OFF = 1<<24, /* disable VLAN stripping */ + RX_MACSEC_FLUSH_ON = 1<<23, + RX_MACSEC_FLUSH_OFF = 1<<22, + RX_MACSEC_ASF_FLUSH_ON = 1<<21, + RX_MACSEC_ASF_FLUSH_OFF = 1<<20, + + GMF_RX_OVER_ON = 1<<19, /* enable flushing on receive overrun */ + GMF_RX_OVER_OFF = 1<<18, /* disable flushing on receive overrun */ + GMF_ASF_RX_OVER_ON = 1<<17, /* enable flushing of ASF when overrun */ + GMF_ASF_RX_OVER_OFF = 1<<16, /* disable flushing of ASF when overrun */ + GMF_WP_TST_ON = 1<<14, /* Write Pointer Test On */ GMF_WP_TST_OFF = 1<<13, /* Write Pointer Test Off */ GMF_WP_STEP = 1<<12, /* Write Pointer Step/Increment */ @@ -1630,6 +1735,10 @@ GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON, }; +/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ +enum { + TX_DYN_WM_ENA = 3, /* Yukon-FE+ specific */ +}; /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ enum { @@ -1720,6 +1829,15 @@ /* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ enum { + GMC_SET_RST = 1<<15,/* MAC SEC RST */ + GMC_SEC_RST_OFF = 1<<14,/* MAC SEC RSt OFF */ + GMC_BYP_MACSECRX_ON = 1<<13,/* Bypass macsec RX */ + GMC_BYP_MACSECRX_OFF= 1<<12,/* Bypass macsec RX off */ + GMC_BYP_MACSECTX_ON = 1<<11,/* Bypass macsec TX */ + GMC_BYP_MACSECTX_OFF= 1<<10,/* Bypass macsec TX off*/ + GMC_BYP_RETR_ON = 1<<9, /* Bypass retransmit FIFO On */ + GMC_BYP_RETR_OFF= 1<<8, /* Bypass retransmit FIFO Off */ + GMC_H_BURST_ON = 1<<7, /* Half Duplex Burst Mode On */ GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */ GMC_F_LOOPB_ON = 1<<5, /* FIFO Loopback On */ @@ -1805,9 +1923,13 @@ OP_ADDR64VLAN = OP_ADDR64 | OP_VLAN, OP_LRGLEN = 0x24, OP_LRGLENVLAN = OP_LRGLEN | OP_VLAN, + OP_MSS = 0x28, + OP_MSSVLAN = OP_MSS | OP_VLAN, + OP_BUFFER = 0x40, OP_PACKET = 0x41, OP_LARGESEND = 0x43, + OP_LSOV2 = 0x45, /* YUKON-2 STATUS opcodes defines */ OP_RXSTAT = 0x60, @@ -1818,6 +1940,19 @@ OP_RXTIMEVLAN = OP_RXTIMESTAMP | OP_RXVLAN, OP_RSS_HASH = 0x65, OP_TXINDEXLE = 0x68, + OP_MACSEC = 0x6c, + OP_PUTIDX = 0x70, +}; + +enum status_css { + CSS_TCPUDPCSOK = 1<<7, /* TCP / UDP checksum is ok */ + CSS_ISUDP = 1<<6, /* packet is a UDP packet */ + CSS_ISTCP = 1<<5, /* packet is a TCP packet */ + CSS_ISIPFRAG = 1<<4, /* packet is a TCP/UDP frag, CS calc not done */ + CSS_ISIPV6 = 1<<3, /* packet is a IPv6 packet */ + CSS_IPV4CSUMOK = 1<<2, /* IP v4: TCP header checksum is ok */ + CSS_ISIPV4 = 1<<1, /* packet is a IPv4 packet */ + CSS_LINK_BIT = 1<<0, /* port number (legacy) */ }; /* Yukon 2 hardware interface */ @@ -1838,7 +1973,7 @@ struct sky2_status_le { __le32 status; /* also checksum */ __le16 length; /* also vlan tag */ - u8 link; + u8 css; u8 opcode; } __attribute((packed)); @@ -1873,6 +2008,7 @@ struct sky2_tx_le *tx_le; u16 tx_cons; /* next le to check */ u16 tx_prod; /* next le to use */ + u16 tx_next; /* debug only */ u32 tx_addr64; u16 tx_pending; u16 tx_last_mss; @@ -1891,6 +2027,14 @@ u16 rx_tag; struct vlan_group *vlgrp; #endif + struct { + unsigned long last; + u32 mac_rp; + u8 mac_lev; + u8 fifo_rp; + u8 fifo_lev; + } check; + dma_addr_t rx_le_map; dma_addr_t tx_le_map; @@ -1903,6 +2047,9 @@ enum flow_control flow_mode; enum flow_control flow_status; +#ifdef CONFIG_SKY2_DEBUG + struct dentry *debugfs; +#endif struct net_device_stats net_stats; }; @@ -1911,6 +2058,15 @@ void __iomem *regs; struct pci_dev *pdev; struct net_device *dev[2]; + unsigned long flags; +#define SKY2_HW_USE_MSI 0x00000001 +#define SKY2_HW_FIBRE_PHY 0x00000002 +#define SKY2_HW_GIGABIT 0x00000004 +#define SKY2_HW_NEWER_PHY 0x00000008 +#define SKY2_HW_FIFO_HANG_CHECK 0x00000010 +#define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */ +#define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ +#define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ u8 chip_id; u8 chip_rev; @@ -1921,15 +2077,14 @@ u32 st_idx; dma_addr_t st_dma; - struct timer_list idle_timer; + struct timer_list watchdog_timer; struct work_struct restart_work; - int msi; wait_queue_head_t msi_wait; }; static inline int sky2_is_copper(const struct sky2_hw *hw) { - return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P'); + return !(hw->flags & SKY2_HW_FIBRE_PHY); } /* Register accessor for memory mapped device */ --- linux-source-2.6.22-2.6.22.orig/drivers/net/forcedeth.c +++ linux-source-2.6.22-2.6.22/drivers/net/forcedeth.c @@ -550,6 +550,8 @@ /* PHY defines */ #define PHY_OUI_MARVELL 0x5043 #define PHY_OUI_CICADA 0x03f1 +#define PHY_OUI_VITESSE 0x01c1 +#define PHY_OUI_REALTEK 0x0732 #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 @@ -557,12 +559,36 @@ #define PHYID2_MODEL_MASK 0x03f0 #define PHY_MODEL_MARVELL_E3016 0x220 #define PHY_MARVELL_E3016_INITMASK 0x0300 -#define PHY_INIT1 0x0f000 -#define PHY_INIT2 0x0e00 -#define PHY_INIT3 0x01000 -#define PHY_INIT4 0x0200 -#define PHY_INIT5 0x0004 -#define PHY_INIT6 0x02000 +#define PHY_CICADA_INIT1 0x0f000 +#define PHY_CICADA_INIT2 0x0e00 +#define PHY_CICADA_INIT3 0x01000 +#define PHY_CICADA_INIT4 0x0200 +#define PHY_CICADA_INIT5 0x0004 +#define PHY_CICADA_INIT6 0x02000 +#define PHY_VITESSE_INIT_REG1 0x1f +#define PHY_VITESSE_INIT_REG2 0x10 +#define PHY_VITESSE_INIT_REG3 0x11 +#define PHY_VITESSE_INIT_REG4 0x12 +#define PHY_VITESSE_INIT_MSK1 0xc +#define PHY_VITESSE_INIT_MSK2 0x0180 +#define PHY_VITESSE_INIT1 0x52b5 +#define PHY_VITESSE_INIT2 0xaf8a +#define PHY_VITESSE_INIT3 0x8 +#define PHY_VITESSE_INIT4 0x8f8a +#define PHY_VITESSE_INIT5 0xaf86 +#define PHY_VITESSE_INIT6 0x8f86 +#define PHY_VITESSE_INIT7 0xaf82 +#define PHY_VITESSE_INIT8 0x0100 +#define PHY_VITESSE_INIT9 0x8f82 +#define PHY_VITESSE_INIT10 0x0 +#define PHY_REALTEK_INIT_REG1 0x1f +#define PHY_REALTEK_INIT_REG2 0x19 +#define PHY_REALTEK_INIT_REG3 0x13 +#define PHY_REALTEK_INIT1 0x0000 +#define PHY_REALTEK_INIT2 0x8e00 +#define PHY_REALTEK_INIT3 0x0001 +#define PHY_REALTEK_INIT4 0xad17 + #define PHY_GIGABIT 0x0100 #define PHY_TIMEOUT 0x1 @@ -1096,6 +1122,28 @@ return PHY_ERROR; } } + if (np->phy_oui == PHY_OUI_REALTEK) { + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } /* set advertise register */ reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); @@ -1141,14 +1189,14 @@ /* phy vendor specific configuration */ if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); - phy_reserved &= ~(PHY_INIT1 | PHY_INIT2); - phy_reserved |= (PHY_INIT3 | PHY_INIT4); + phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); + phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); return PHY_ERROR; } phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); - phy_reserved |= PHY_INIT5; + phy_reserved |= PHY_CICADA_INIT5; if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); return PHY_ERROR; @@ -1156,12 +1204,106 @@ } if (np->phy_oui == PHY_OUI_CICADA) { phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); - phy_reserved |= PHY_INIT6; + phy_reserved |= PHY_CICADA_INIT6; if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); return PHY_ERROR; } } + if (np->phy_oui == PHY_OUI_VITESSE) { + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK1; + phy_reserved |= PHY_VITESSE_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK1; + phy_reserved |= PHY_VITESSE_INIT3; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ); + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ); + phy_reserved &= ~PHY_VITESSE_INIT_MSK2; + phy_reserved |= PHY_VITESSE_INIT8; + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_oui == PHY_OUI_REALTEK) { + /* reset could have cleared these out, set them back */ + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + /* some phys clear out pause advertisment on reset, set it back */ mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); @@ -2925,8 +3067,8 @@ np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3043,8 +3185,8 @@ np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3090,8 +3232,8 @@ np->nic_poll_irq |= NVREG_IRQ_TX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); break; } @@ -3205,8 +3347,8 @@ np->nic_poll_irq |= NVREG_IRQ_RX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); break; } } @@ -3278,8 +3420,8 @@ np->nic_poll_irq |= NVREG_IRQ_OTHER; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); break; } @@ -5408,6 +5550,22 @@ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, + { /* MCP73 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP73 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP73 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP73 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, {0,}, }; --- linux-source-2.6.22-2.6.22.orig/drivers/net/Makefile +++ linux-source-2.6.22-2.6.22/drivers/net/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o obj-$(CONFIG_CASSINI) += cassini.o +obj-$(CONFIG_SUNVNET) += sunvnet.o obj-$(CONFIG_MACE) += mace.o obj-$(CONFIG_BMAC) += bmac.o @@ -227,3 +228,4 @@ obj-$(CONFIG_FS_ENET) += fs_enet/ obj-$(CONFIG_NETXEN_NIC) += netxen/ +obj-$(CONFIG_NIU) += niu.o --- linux-source-2.6.22-2.6.22.orig/drivers/net/ppp_synctty.c +++ linux-source-2.6.22-2.6.22/drivers/net/ppp_synctty.c @@ -207,6 +207,9 @@ struct syncppp *ap; int err; + if (!tty->driver->write) + return -EOPNOTSUPP; + ap = kmalloc(sizeof(*ap), GFP_KERNEL); err = -ENOMEM; if (ap == 0) --- linux-source-2.6.22-2.6.22.orig/drivers/net/natsemi.c +++ linux-source-2.6.22-2.6.22/drivers/net/natsemi.c @@ -671,7 +671,7 @@ #define NATSEMI_CREATE_FILE(_dev, _name) \ device_create_file(&_dev->dev, &dev_attr_##_name) #define NATSEMI_REMOVE_FILE(_dev, _name) \ - device_create_file(&_dev->dev, &dev_attr_##_name) + device_remove_file(&_dev->dev, &dev_attr_##_name) NATSEMI_ATTR(dspcfg_workaround); --- linux-source-2.6.22-2.6.22.orig/drivers/net/irda/irtty-sir.c +++ linux-source-2.6.22-2.6.22/drivers/net/irda/irtty-sir.c @@ -64,7 +64,9 @@ IRDA_ASSERT(priv != NULL, return -1;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); - return priv->tty->driver->chars_in_buffer(priv->tty); + if (priv->tty->driver->chars_in_buffer) + return priv->tty->driver->chars_in_buffer(priv->tty); + return 0; } /* Wait (sleep) until underlaying hardware finished transmission --- linux-source-2.6.22-2.6.22.orig/drivers/net/irda/nsc-ircc.c +++ linux-source-2.6.22-2.6.22/drivers/net/irda/nsc-ircc.c @@ -149,7 +149,7 @@ static chipio_t pnp_info; static const struct pnp_device_id nsc_ircc_pnp_table[] = { { .id = "NSC6001", .driver_data = 0 }, - { .id = "IBM0071", .driver_data = 0 }, + { .id = "IBM0071", .driver_data = 1 }, { } }; @@ -929,6 +929,9 @@ * On my box, cfg_base is in the PnP descriptor of the * motherboard. Oh well... Jean II */ + if (id->driver_data == 1) + dongle_id = 0x9; + if (pnp_port_valid(dev, 0) && !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) pnp_info.fir_base = pnp_port_start(dev, 0); --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/strip.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/strip.c @@ -801,7 +801,8 @@ struct ktermios old_termios = *(tty->termios); tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */ tty->termios->c_cflag |= baudcode; /* Set the new baud setting */ - tty->driver->set_termios(tty, &old_termios); + if (tty->driver->set_termios) + tty->driver->set_termios(tty, &old_termios); } /* --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/ipw2100.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/ipw2100.c @@ -7865,10 +7865,10 @@ goto done; } - if ((mode < 1) || (mode > POWER_MODES)) + if ((mode < 0) || (mode > POWER_MODES)) mode = IPW_POWER_AUTO; - if (priv->power_mode != mode) + if (IPW_POWER_LEVEL(priv->power_mode) != mode) err = ipw2100_set_power_mode(priv, mode); done: mutex_unlock(&priv->action_mutex); @@ -7899,7 +7899,7 @@ break; case IPW_POWER_AUTO: snprintf(extra, MAX_POWER_STRING, - "Power save level: %d (Auto)", 0); + "Power save level: %d (Auto)", level); break; default: timeout = timeout_duration[level - 1] / 1000; --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/hostap/hostap_hw.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/hostap/hostap_hw.c @@ -3432,6 +3432,7 @@ memset(&wrqu, 0, sizeof(wrqu)); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); /* Disable hardware and firmware */ prism2_hw_shutdown(dev, 0); --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/hostap/hostap_main.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/hostap/hostap_main.c @@ -1086,6 +1086,7 @@ (u8 *) &reason, 2); memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); return ret; } --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/hostap/hostap_cs.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/hostap/hostap_cs.c @@ -824,6 +824,7 @@ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x3301), PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b), PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/hostap/hostap_info.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/hostap/hostap_info.c @@ -235,6 +235,7 @@ wrqu.data.length = 0; wrqu.data.flags = 0; wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWSCAN, &wrqu, NULL); /* Allow SIOCGIWSCAN handling to occur since we have received * scanning result */ @@ -445,8 +446,10 @@ * frames and can confuse wpa_supplicant about the current association * status. */ - if (connected || local->prev_linkstatus_connected) + if (connected || local->prev_linkstatus_connected) { wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); + } local->prev_linkstatus_connected = connected; } --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/zd1211rw/zd_usb.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/zd1211rw/zd_usb.c @@ -70,6 +70,7 @@ { USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3183,6 +3183,9 @@ unsigned long orig_trans_start = 0; mutex_lock(&bcm->mutex); + /* keep from doing and rearming periodic work if shutting down */ + if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT) + goto unlock_mutex; if (unlikely(bcm->periodic_state % 60 == 0)) { /* Periodic work will take a long time, so we want it to * be preemtible. @@ -3228,14 +3231,10 @@ mmiowb(); bcm->periodic_state++; spin_unlock_irqrestore(&bcm->irq_lock, flags); +unlock_mutex: mutex_unlock(&bcm->mutex); } -void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) -{ - cancel_rearming_delayed_work(&bcm->periodic_work); -} - void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) { struct delayed_work *work = &bcm->periodic_work; @@ -3285,6 +3284,14 @@ return err; } +void bcm43xx_cancel_work(struct bcm43xx_private *bcm) +{ + /* The system must be unlocked when this routine is entered. + * If not, the next 2 steps may deadlock */ + cancel_work_sync(&bcm->restart_work); + cancel_rearming_delayed_work(&bcm->periodic_work); +} + static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm) { int ret = 0; @@ -3321,7 +3328,12 @@ { bcm43xx_rng_exit(bcm); bcm43xx_sysfs_unregister(bcm); - bcm43xx_periodic_tasks_delete(bcm); + + mutex_lock(&(bcm)->mutex); + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); + mutex_unlock(&(bcm)->mutex); + + bcm43xx_cancel_work(bcm); mutex_lock(&(bcm)->mutex); bcm43xx_shutdown_all_wireless_cores(bcm); @@ -4018,7 +4030,7 @@ err = bcm43xx_disable_interrupts_sync(bcm); assert(!err); bcm43xx_free_board(bcm); - flush_scheduled_work(); + bcm43xx_cancel_work(bcm); return 0; } @@ -4150,9 +4162,9 @@ struct bcm43xx_phyinfo *phy; int err = -ENODEV; + bcm43xx_cancel_work(bcm); mutex_lock(&(bcm)->mutex); if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { - bcm43xx_periodic_tasks_delete(bcm); phy = bcm43xx_current_phy(bcm); err = bcm43xx_select_wireless_core(bcm, phy->type); if (!err) --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -327,7 +327,7 @@ goto out; } - bcm43xx_periodic_tasks_delete(bcm); + bcm43xx_cancel_work(bcm); mutex_lock(&(bcm)->mutex); err = bcm43xx_select_wireless_core(bcm, phytype); if (!err) --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/bcm43xx/bcm43xx_main.h @@ -122,7 +122,7 @@ void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); void bcm43xx_mac_enable(struct bcm43xx_private *bcm); -void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm); +void bcm43xx_cancel_work(struct bcm43xx_private *bcm); void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm); void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/ipw2200.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/ipw2200.c @@ -2506,7 +2506,7 @@ break; } - param = cpu_to_le32(mode); + param = cpu_to_le32(param); return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), ¶m); } @@ -9567,6 +9567,7 @@ priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; else priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; + err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); @@ -9603,22 +9604,19 @@ struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; int err; + mutex_lock(&priv->mutex); - if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { + if ((mode < 1) || (mode > IPW_POWER_LIMIT)) mode = IPW_POWER_AC; - priv->power_mode = mode; - } else { - priv->power_mode = IPW_POWER_ENABLED | mode; - } - if (priv->power_mode != mode) { + if (IPW_POWER_LEVEL(priv->power_mode) != mode) { err = ipw_send_power_mode(priv, mode); - if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); mutex_unlock(&priv->mutex); return err; } + priv->power_mode = IPW_POWER_ENABLED | mode; } mutex_unlock(&priv->mutex); return 0; --- linux-source-2.6.22-2.6.22.orig/drivers/net/wireless/orinoco_cs.c +++ linux-source-2.6.22-2.6.22/drivers/net/wireless/orinoco_cs.c @@ -11,6 +11,7 @@ */ #define DRIVER_NAME "orinoco_cs" +#define OVERLAP_DRIVER_NAME "orinoco_cs_overlap" #define PFX DRIVER_NAME ": " #include @@ -441,66 +442,93 @@ " (David Gibson , " "Pavel Roskin , et al)"; -static struct pcmcia_device_id orinoco_cs_ids[] = { +/* + * PCMCIA IDs that are also defined in hostap_cs. + */ +static struct pcmcia_device_id orinoco_overlap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ - PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ + PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ + PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), + PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), + + PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), + + PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), + PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), + PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), + PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), + PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), + PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), + PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), + PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), + + PCMCIA_DEVICE_NULL, +}; + +static struct pcmcia_driver orinoco_overlap_driver = { + .owner = THIS_MODULE, + .drv = { + .name = OVERLAP_DRIVER_NAME, + }, + .probe = orinoco_cs_probe, + .remove = orinoco_cs_detach, + .id_table = orinoco_overlap_cs_ids, + .suspend = orinoco_cs_suspend, + .resume = orinoco_cs_resume, +}; + +static struct pcmcia_device_id orinoco_cs_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ - PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ - PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ - PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ - PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), - PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092), - PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), - PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), - PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), - PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), - PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), - PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), - PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), - PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), @@ -517,11 +545,8 @@ PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), - PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); @@ -538,18 +563,39 @@ .resume = orinoco_cs_resume, }; +static int orinoco_driver_registered = 0; +static int orinoco_overlap_driver_registered = 0; + static int __init init_orinoco_cs(void) { + int status; + printk(KERN_DEBUG "%s\n", version); - return pcmcia_register_driver(&orinoco_driver); + status = pcmcia_register_driver(&orinoco_driver); + if (status >= 0) + orinoco_driver_registered = 1; + + status = pcmcia_register_driver(&orinoco_overlap_driver); + if (status >= 0) + orinoco_overlap_driver_registered = 1; + + return status; } static void __exit exit_orinoco_cs(void) { - pcmcia_unregister_driver(&orinoco_driver); + if (orinoco_overlap_driver_registered) { + pcmcia_unregister_driver(&orinoco_overlap_driver); + orinoco_overlap_driver_registered = 0; + } + + if (orinoco_driver_registered) { + pcmcia_unregister_driver(&orinoco_driver); + orinoco_driver_registered = 0; + } } module_init(init_orinoco_cs); --- linux-source-2.6.22-2.6.22.orig/drivers/net/ppp_generic.c +++ linux-source-2.6.22-2.6.22/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + skb->len + 2, ns->data, obuff_size); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ --- linux-source-2.6.22-2.6.22.orig/drivers/net/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/net/Kconfig @@ -574,6 +574,12 @@ Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also +config SUNVNET + tristate "Sun Virtual Network support" + depends on SUN_LDOMS + help + Support for virtual network devices under Sun Logical Domains. + config NET_VENDOR_3COM bool "3COM cards" depends on NET_ETHERNET && (ISA || EISA || MCA || PCI) @@ -2493,6 +2499,13 @@ help This enables the support for NetXen's Gigabit Ethernet card. +config NIU + tristate "Sun Neptune 10Gbit Ethernet support" + depends on PCI + help + This enables support for cards based upon Sun's + Neptune chipset. + config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" depends on PPC64 && PCI --- linux-source-2.6.22-2.6.22.orig/drivers/net/ppp_async.c +++ linux-source-2.6.22-2.6.22/drivers/net/ppp_async.c @@ -158,6 +158,9 @@ struct asyncppp *ap; int err; + if (!tty->driver->write) + return -EOPNOTSUPP; + err = -ENOMEM; ap = kmalloc(sizeof(*ap), GFP_KERNEL); if (ap == 0) --- linux-source-2.6.22-2.6.22.orig/drivers/net/hamradio/6pack.c +++ linux-source-2.6.22-2.6.22/drivers/net/hamradio/6pack.c @@ -596,6 +596,8 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup); if (!dev) { --- linux-source-2.6.22-2.6.22.orig/drivers/net/hamradio/mkiss.c +++ linux-source-2.6.22-2.6.22/drivers/net/hamradio/mkiss.c @@ -530,6 +530,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) { struct mkiss *ax = netdev_priv(dev); + int cib = 0; if (!netif_running(dev)) { printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); @@ -545,10 +546,11 @@ /* 20 sec timeout not reached */ return 1; } + if (ax->tty->driver->chars_in_buffer) + cib = ax->tty->driver->chars_in_buffer(ax->tty); printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name, - (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ? - "bad line quality" : "driver error"); + cib || ax->xleft ? "bad line quality" : "driver error"); ax->xleft = 0; clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); @@ -731,6 +733,8 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); if (!dev) { --- linux-source-2.6.22-2.6.22.orig/drivers/net/tulip/tulip.h +++ linux-source-2.6.22-2.6.22/drivers/net/tulip/tulip.h @@ -37,7 +37,10 @@ #define TULIP_BAR 0 /* CBIO */ #endif - +#ifndef PCI_ULI5261_ID +#define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/ +#define PCI_ULI5263_ID 0x526310B9 /* ULi M5263 ID*/ +#endif struct tulip_chip_table { char *chip_name; --- linux-source-2.6.22-2.6.22.orig/drivers/net/tulip/tulip_core.c +++ linux-source-2.6.22-2.6.22/drivers/net/tulip/tulip_core.c @@ -230,8 +230,12 @@ { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, + /* Ubuntu: On non-sparc, this seems to be handled better by the + * dmfe driver. */ +#ifdef __sparc__ { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, +#endif { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, @@ -389,6 +393,11 @@ goto media_picked; } } + if (tp->chip_id == PCI_ULI5261_ID || tp->chip_id == PCI_ULI5263_ID) { + for (i = tp->mtable->leafcount - 1; i >= 0; i--) + if (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaIsMII) + goto media_picked; + } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) --- linux-source-2.6.22-2.6.22.orig/drivers/net/tulip/media.c +++ linux-source-2.6.22-2.6.22/drivers/net/tulip/media.c @@ -519,10 +519,11 @@ /* Enable autonegotiation: some boards default to off. */ if (tp->default_port == 0) { new_bmcr = mii_reg0 | BMCR_ANENABLE; - if (new_bmcr != mii_reg0) { - new_bmcr |= BMCR_ANRESTART; - ane_switch = 1; - } + /* DM9161E PHY seems to need to restart + * autonegotiation even if it defaults to enabled. + */ + new_bmcr |= BMCR_ANRESTART; + ane_switch = 1; } /* ...or disable nway, if forcing media */ else { --- linux-source-2.6.22-2.6.22.orig/drivers/net/sunvnet.h +++ linux-source-2.6.22-2.6.22/drivers/net/sunvnet.h @@ -0,0 +1,83 @@ +#ifndef _SUNVNET_H +#define _SUNVNET_H + +#define DESC_NCOOKIES(entry_size) \ + ((entry_size) - sizeof(struct vio_net_desc)) + +/* length of time before we decide the hardware is borked, + * and dev->tx_timeout() should be called to fix the problem + */ +#define VNET_TX_TIMEOUT (5 * HZ) + +#define VNET_TX_RING_SIZE 512 +#define VNET_TX_WAKEUP_THRESH(dr) ((dr)->pending / 4) + +/* VNET packets are sent in buffers with the first 6 bytes skipped + * so that after the ethernet header the IPv4/IPv6 headers are aligned + * properly. + */ +#define VNET_PACKET_SKIP 6 + +struct vnet_tx_entry { + void *buf; + unsigned int ncookies; + struct ldc_trans_cookie cookies[2]; +}; + +struct vnet; +struct vnet_port { + struct vio_driver_state vio; + + struct hlist_node hash; + u8 raddr[ETH_ALEN]; + u8 switch_port; + u8 __pad; + + struct vnet *vp; + + struct vnet_tx_entry tx_bufs[VNET_TX_RING_SIZE]; + + struct list_head list; +}; + +static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio) +{ + return container_of(vio, struct vnet_port, vio); +} + +#define VNET_PORT_HASH_SIZE 16 +#define VNET_PORT_HASH_MASK (VNET_PORT_HASH_SIZE - 1) + +static inline unsigned int vnet_hashfn(u8 *mac) +{ + unsigned int val = mac[4] ^ mac[5]; + + return val & (VNET_PORT_HASH_MASK); +} + +struct vnet_mcast_entry { + u8 addr[ETH_ALEN]; + u8 sent; + u8 hit; + struct vnet_mcast_entry *next; +}; + +struct vnet { + /* Protects port_list and port_hash. */ + spinlock_t lock; + + struct net_device *dev; + + u32 msg_enable; + + struct list_head port_list; + + struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; + + struct vnet_mcast_entry *mcast_list; + + struct list_head list; + u64 local_mac; +}; + +#endif /* _SUNVNET_H */ --- linux-source-2.6.22-2.6.22.orig/drivers/net/wan/x25_asy.c +++ linux-source-2.6.22-2.6.22/drivers/net/wan/x25_asy.c @@ -283,6 +283,10 @@ static void x25_asy_timeout(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); + int cib = 0; + + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { @@ -290,8 +294,7 @@ * 14 Oct 1994 Dmitry Gorodchanin. */ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + (cib || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); x25_asy_unlock(sl); @@ -561,6 +564,9 @@ return -EEXIST; } + if (!tty->driver->write) + return -EOPNOTSUPP; + /* OK. Find a free X.25 channel to use. */ if ((sl = x25_asy_alloc()) == NULL) { return -ENFILE; --- linux-source-2.6.22-2.6.22.orig/drivers/net/r8169.c +++ linux-source-2.6.22-2.6.22/drivers/net/r8169.c @@ -1,53 +1,11 @@ /* -========================================================================= - r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x. - -------------------------------------------------------------------- - - History: - Feb 4 2002 - created initially by ShuChen . - May 20 2002 - Add link status force-mode and TBI mode support. - 2004 - Massive updates. See kernel SCM system for details. -========================================================================= - 1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes. - Command: 'insmod r8169 media = SET_MEDIA' - Ex: 'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex. - - SET_MEDIA can be: - _10_Half = 0x01 - _10_Full = 0x02 - _100_Half = 0x04 - _100_Full = 0x08 - _1000_Full = 0x10 - - 2. Support TBI mode. -========================================================================= -VERSION 1.1 <2002/10/4> - - The bit4:0 of MII register 4 is called "selector field", and have to be - 00001b to indicate support of IEEE std 802.3 during NWay process of - exchanging Link Code Word (FLP). - -VERSION 1.2 <2002/11/30> - - - Large style cleanup - - Use ether_crc in stock kernel (linux/crc32.h) - - Copy mc_filter setup code from 8139cp - (includes an optimization, and avoids set_bit use) - -VERSION 1.6LK <2004/04/14> - - - Merge of Realtek's version 1.6 - - Conversion to DMA API - - Suspend/resume - - Endianness - - Misc Rx/Tx bugs - -VERSION 2.2LK <2005/01/25> - - - RX csum, TX csum/SG, TSO - - VLAN - - baby (< 7200) Jumbo frames support - - Merge of Realtek's version 2.2 (new phy) + * r8169.c: RealTek 8169/8168/8101 ethernet driver. + * + * Copyright (c) 2002 ShuChen + * Copyright (c) 2003 - 2007 Francois Romieu + * Copyright (c) a lot of people too. Please respect their work. + * + * See MAINTAINERS file for support contact information. */ #include @@ -108,11 +66,6 @@ #define rtl8169_rx_quota(count, quota) count #endif -/* media options */ -#define MAX_UNITS 8 -static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int num_media = 0; - /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static const int max_interrupt_work = 20; @@ -126,7 +79,7 @@ #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ +#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ #define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -151,16 +104,17 @@ #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) enum mac_version { - RTL_GIGA_MAC_VER_01 = 0x00, - RTL_GIGA_MAC_VER_02 = 0x01, - RTL_GIGA_MAC_VER_03 = 0x02, - RTL_GIGA_MAC_VER_04 = 0x03, - RTL_GIGA_MAC_VER_05 = 0x04, - RTL_GIGA_MAC_VER_11 = 0x0b, - RTL_GIGA_MAC_VER_12 = 0x0c, - RTL_GIGA_MAC_VER_13 = 0x0d, - RTL_GIGA_MAC_VER_14 = 0x0e, - RTL_GIGA_MAC_VER_15 = 0x0f + RTL_GIGA_MAC_VER_01 = 0x01, // 8169 + RTL_GIGA_MAC_VER_02 = 0x02, // 8169S + RTL_GIGA_MAC_VER_03 = 0x03, // 8110S + RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB + RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd + RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe + RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb + RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf + RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec + RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 + RTL_GIGA_MAC_VER_15 = 0x0f // 8101 }; enum phy_version { @@ -180,11 +134,12 @@ u8 mac_version; u32 RxConfigMask; /* Clears the bits supported by this chip */ } rtl_chip_info[] = { - _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), - _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), + _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 + _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S + _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S + _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 @@ -199,20 +154,15 @@ RTL_CFG_2 }; -static const struct { - unsigned int region; - unsigned int align; -} rtl_cfg_info[] = { - [RTL_CFG_0] = { 1, NET_IP_ALIGN }, - [RTL_CFG_1] = { 2, NET_IP_ALIGN }, - [RTL_CFG_2] = { 2, 8 } -}; +static void rtl_hw_start_8169(struct net_device *); +static void rtl_hw_start_8168(struct net_device *); +static void rtl_hw_start_8101(struct net_device *); static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, @@ -230,62 +180,63 @@ u32 msg_enable; } debug = { -1 }; -enum RTL8169_registers { - MAC0 = 0, /* Ethernet hardware address. */ - MAR0 = 8, /* Multicast filter. */ - CounterAddrLow = 0x10, - CounterAddrHigh = 0x14, - TxDescStartAddrLow = 0x20, - TxDescStartAddrHigh = 0x24, - TxHDescStartAddrLow = 0x28, - TxHDescStartAddrHigh = 0x2c, - FLASH = 0x30, - ERSR = 0x36, - ChipCmd = 0x37, - TxPoll = 0x38, - IntrMask = 0x3C, - IntrStatus = 0x3E, - TxConfig = 0x40, - RxConfig = 0x44, - RxMissed = 0x4C, - Cfg9346 = 0x50, - Config0 = 0x51, - Config1 = 0x52, - Config2 = 0x53, - Config3 = 0x54, - Config4 = 0x55, - Config5 = 0x56, - MultiIntr = 0x5C, - PHYAR = 0x60, - TBICSR = 0x64, - TBI_ANAR = 0x68, - TBI_LPAR = 0x6A, - PHYstatus = 0x6C, - RxMaxSize = 0xDA, - CPlusCmd = 0xE0, - IntrMitigate = 0xE2, - RxDescAddrLow = 0xE4, - RxDescAddrHigh = 0xE8, - EarlyTxThres = 0xEC, - FuncEvent = 0xF0, - FuncEventMask = 0xF4, - FuncPresetState = 0xF8, - FuncForceEvent = 0xFC, +enum rtl_registers { + MAC0 = 0, /* Ethernet hardware address. */ + MAC4 = 4, + MAR0 = 8, /* Multicast filter. */ + CounterAddrLow = 0x10, + CounterAddrHigh = 0x14, + TxDescStartAddrLow = 0x20, + TxDescStartAddrHigh = 0x24, + TxHDescStartAddrLow = 0x28, + TxHDescStartAddrHigh = 0x2c, + FLASH = 0x30, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, + IntrMask = 0x3c, + IntrStatus = 0x3e, + TxConfig = 0x40, + RxConfig = 0x44, + RxMissed = 0x4c, + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, + MultiIntr = 0x5c, + PHYAR = 0x60, + TBICSR = 0x64, + TBI_ANAR = 0x68, + TBI_LPAR = 0x6a, + PHYstatus = 0x6c, + RxMaxSize = 0xda, + CPlusCmd = 0xe0, + IntrMitigate = 0xe2, + RxDescAddrLow = 0xe4, + RxDescAddrHigh = 0xe8, + EarlyTxThres = 0xec, + FuncEvent = 0xf0, + FuncEventMask = 0xf4, + FuncPresetState = 0xf8, + FuncForceEvent = 0xfc, }; -enum RTL8169_register_content { +enum rtl_register_content { /* InterruptStatusBits */ - SYSErr = 0x8000, - PCSTimeout = 0x4000, - SWInt = 0x0100, - TxDescUnavail = 0x80, - RxFIFOOver = 0x40, - LinkChg = 0x20, - RxOverflow = 0x10, - TxErr = 0x08, - TxOK = 0x04, - RxErr = 0x02, - RxOK = 0x01, + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x0080, + RxFIFOOver = 0x0040, + LinkChg = 0x0020, + RxOverflow = 0x0010, + TxErr = 0x0008, + TxOK = 0x0004, + RxErr = 0x0002, + RxOK = 0x0001, /* RxStatusDesc */ RxFOVF = (1 << 23), @@ -295,26 +246,31 @@ RxCRC = (1 << 19), /* ChipCmdBits */ - CmdReset = 0x10, - CmdRxEnb = 0x08, - CmdTxEnb = 0x04, - RxBufEmpty = 0x01, + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, + + /* TXPoll register p.5 */ + HPQ = 0x80, /* Poll cmd on the high prio queue */ + NPQ = 0x40, /* Poll cmd on the low prio queue */ + FSWInt = 0x01, /* Forced software interrupt */ /* Cfg9346Bits */ - Cfg9346_Lock = 0x00, - Cfg9346_Unlock = 0xC0, + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xc0, /* rx_mode_bits */ - AcceptErr = 0x20, - AcceptRunt = 0x10, - AcceptBroadcast = 0x08, - AcceptMulticast = 0x04, - AcceptMyPhys = 0x02, - AcceptAllPhys = 0x01, + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, /* RxConfigBits */ - RxCfgFIFOShift = 13, - RxCfgDMAShift = 8, + RxCfgFIFOShift = 13, + RxCfgDMAShift = 8, /* TxConfigBits */ TxInterFrameGapShift = 24, @@ -323,6 +279,10 @@ /* Config1 register p.24 */ PMEnable = (1 << 0), /* Power Management Enable */ + /* Config2 register p. 25 */ + PCI_Clock_66MHz = 0x01, + PCI_Clock_33MHz = 0x00, + /* Config3 register p.25 */ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ @@ -343,36 +303,34 @@ TBINwComplete = 0x01000000, /* CPlusCmd p.31 */ + PktCntrDisable = (1 << 7), // 8168 RxVlan = (1 << 6), RxChkSum = (1 << 5), PCIDAC = (1 << 4), PCIMulRW = (1 << 3), + INTT_0 = 0x0000, // 8168 + INTT_1 = 0x0001, // 8168 + INTT_2 = 0x0002, // 8168 + INTT_3 = 0x0003, // 8168 /* rtl8169_PHYstatus */ - TBI_Enable = 0x80, - TxFlowCtrl = 0x40, - RxFlowCtrl = 0x20, - _1000bpsF = 0x10, - _100bps = 0x08, - _10bps = 0x04, - LinkStatus = 0x02, - FullDup = 0x01, - - /* _MediaType */ - _10_Half = 0x01, - _10_Full = 0x02, - _100_Half = 0x04, - _100_Full = 0x08, - _1000_Full = 0x10, + TBI_Enable = 0x80, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, /* _TBICSRBit */ - TBILinkOK = 0x02000000, + TBILinkOK = 0x02000000, /* DumpCounterCommand */ - CounterDump = 0x8, + CounterDump = 0x8, }; -enum _DescStatusBit { +enum desc_status_bit { DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ @@ -405,15 +363,15 @@ #define RsvdMask 0x3fffc000 struct TxDesc { - u32 opts1; - u32 opts2; - u64 addr; + __le32 opts1; + __le32 opts2; + __le64 addr; }; struct RxDesc { - u32 opts1; - u32 opts2; - u64 addr; + __le32 opts1; + __le32 opts2; + __le64 addr; }; struct ring_info { @@ -446,6 +404,8 @@ unsigned rx_buf_sz; struct timer_list timer; u16 cp_cmd; + u16 intr_event; + u16 napi_event; u16 intr_mask; int phy_auto_nego_reg; int phy_1000_ctrl_reg; @@ -455,6 +415,7 @@ int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); void (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(void __iomem *); + void (*hw_start)(struct net_device *); unsigned int (*phy_reset_pending)(void __iomem *); unsigned int (*link_ok)(void __iomem *); struct delayed_work task; @@ -463,8 +424,6 @@ MODULE_AUTHOR("Realtek and the Linux r8169 crew "); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); -module_param_array(media, int, &num_media, 0); -MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8)."); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); @@ -478,9 +437,9 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance); static int rtl8169_init_ring(struct net_device *dev); -static void rtl8169_hw_start(struct net_device *dev); +static void rtl_hw_start(struct net_device *dev); static int rtl8169_close(struct net_device *dev); -static void rtl8169_set_rx_mode(struct net_device *dev); +static void rtl_set_rx_mode(struct net_device *dev); static void rtl8169_tx_timeout(struct net_device *dev); static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, @@ -493,35 +452,37 @@ static int rtl8169_poll(struct net_device *dev, int *budget); #endif -static const u16 rtl8169_intr_mask = - SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; -static const u16 rtl8169_napi_event = - RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr; static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); -static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) +static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) { int i; - RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); + RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value); for (i = 20; i > 0; i--) { - /* Check if the RTL8169 has completed writing to the specified MII register */ + /* + * Check if the RTL8169 has completed writing to the specified + * MII register. + */ if (!(RTL_R32(PHYAR) & 0x80000000)) break; udelay(25); } } -static int mdio_read(void __iomem *ioaddr, int RegAddr) +static int mdio_read(void __iomem *ioaddr, int reg_addr) { int i, value = -1; - RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); + RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16); for (i = 20; i > 0; i--) { - /* Check if the RTL8169 has completed retrieving data from the specified MII register */ + /* + * Check if the RTL8169 has completed retrieving data from + * the specified MII register. + */ if (RTL_R32(PHYAR) & 0x80000000) { value = (int) (RTL_R32(PHYAR) & 0xFFFF); break; @@ -579,7 +540,8 @@ } static void rtl8169_check_link_status(struct net_device *dev, - struct rtl8169_private *tp, void __iomem *ioaddr) + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned long flags; @@ -596,38 +558,6 @@ spin_unlock_irqrestore(&tp->lock, flags); } -static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex) -{ - struct { - u16 speed; - u8 duplex; - u8 autoneg; - u8 media; - } link_settings[] = { - { SPEED_10, DUPLEX_HALF, AUTONEG_DISABLE, _10_Half }, - { SPEED_10, DUPLEX_FULL, AUTONEG_DISABLE, _10_Full }, - { SPEED_100, DUPLEX_HALF, AUTONEG_DISABLE, _100_Half }, - { SPEED_100, DUPLEX_FULL, AUTONEG_DISABLE, _100_Full }, - { SPEED_1000, DUPLEX_FULL, AUTONEG_DISABLE, _1000_Full }, - /* Make TBI happy */ - { SPEED_1000, DUPLEX_FULL, AUTONEG_ENABLE, 0xff } - }, *p; - unsigned char option; - - option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff; - - if ((option != 0xff) && !idx && netif_msg_drv(&debug)) - printk(KERN_WARNING PFX "media option is deprecated.\n"); - - for (p = link_settings; p->media != 0xff; p++) { - if (p->media == option) - break; - } - *autoneg = p->autoneg; - *speed = p->speed; - *duplex = p->duplex; -} - static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); @@ -667,7 +597,7 @@ { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - int i; + unsigned int i; static struct { u32 opt; u16 reg; @@ -795,6 +725,12 @@ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (tp->mac_version == RTL_GIGA_MAC_VER_12) { + /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */ + mdio_write(ioaddr, 0x1f, 0x0000); + mdio_write(ioaddr, 0x0e, 0x0000); + } + tp->phy_auto_nego_reg = auto_nego; tp->phy_1000_ctrl_reg = giga_ctrl; @@ -893,8 +829,7 @@ int ret; if (tp->vlgrp && (opts2 & RxVlanTag)) { - rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, - swab16(opts2 & 0xffff)); + rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff)); ret = 0; } else ret = -1; @@ -1115,7 +1050,6 @@ } } - static const struct ethtool_ops rtl8169_ethtool_ops = { .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, @@ -1138,11 +1072,10 @@ .get_strings = rtl8169_get_strings, .get_stats_count = rtl8169_get_stats_count, .get_ethtool_stats = rtl8169_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, }; -static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum, - int bitval) +static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, + int bitnum, int bitval) { int val; @@ -1152,8 +1085,20 @@ mdio_write(ioaddr, reg, val & 0xffff); } -static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) +static void rtl8169_get_mac_version(struct rtl8169_private *tp, + void __iomem *ioaddr) { + /* + * The driver currently handles the 8168Bf and the 8168Be identically + * but they can be identified more specifically through the test below + * if needed: + * + * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be + * + * Same thing for the 8101Eb and the 8101Ec: + * + * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec + */ const struct { u32 mask; int mac_version; @@ -1163,6 +1108,7 @@ { 0x34000000, RTL_GIGA_MAC_VER_13 }, { 0x30800000, RTL_GIGA_MAC_VER_14 }, { 0x30000000, RTL_GIGA_MAC_VER_11 }, + { 0x98000000, RTL_GIGA_MAC_VER_06 }, { 0x18000000, RTL_GIGA_MAC_VER_05 }, { 0x10000000, RTL_GIGA_MAC_VER_04 }, { 0x04000000, RTL_GIGA_MAC_VER_03 }, @@ -1171,7 +1117,7 @@ }, *p = mac_info; u32 reg; - reg = RTL_R32(TxConfig) & 0x7c800000; + reg = RTL_R32(TxConfig) & 0xfc800000; while ((reg & p->mask) != p->mask) p++; tp->mac_version = p->mac_version; @@ -1182,7 +1128,8 @@ dprintk("mac_version = 0x%02x\n", tp->mac_version); } -static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) +static void rtl8169_get_phy_version(struct rtl8169_private *tp, + void __iomem *ioaddr) { const struct { u16 mask; @@ -1259,7 +1206,7 @@ 0xbf00 } //w 0 15 0 bf00 } }, *p = phy_magic; - int i; + unsigned int i; rtl8169_print_mac_version(tp); rtl8169_print_phy_version(tp); @@ -1281,7 +1228,10 @@ return; } - /* phy config for RTL8169s mac_version C chip */ + if ((tp->mac_version != RTL_GIGA_MAC_VER_02) && + (tp->mac_version != RTL_GIGA_MAC_VER_03)) + return; + mdio_write(ioaddr, 31, 0x0001); //w 31 2 0 1 mdio_write(ioaddr, 21, 0x1000); //w 21 15 0 1000 mdio_write(ioaddr, 24, 0x65c7); //w 24 15 0 65c7 @@ -1393,7 +1343,7 @@ struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - int i; + unsigned int i; tp->phy_reset_enable(ioaddr); for (i = 0; i < 100; i++) { @@ -1408,21 +1358,16 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - static int board_idx = -1; - u8 autoneg, duplex; - u16 speed; - - board_idx++; rtl8169_hw_phy_config(dev); dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); RTL_W8(0x82, 0x01); - if (tp->mac_version < RTL_GIGA_MAC_VER_03) { - dprintk("Set PCI Latency=0x40\n"); - pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); - } + pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); + + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); if (tp->mac_version == RTL_GIGA_MAC_VER_02) { dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); @@ -1431,16 +1376,52 @@ mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 } - rtl8169_link_option(board_idx, &autoneg, &speed, &duplex); - rtl8169_phy_reset(dev, tp); - rtl8169_set_speed(dev, autoneg, speed, duplex); + /* + * rtl8169_set_speed_xmii takes good care of the Fast Ethernet + * only 8101. Don't panic. + */ + rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL); if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp)) printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); } +static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 high; + u32 low; + + low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); + high = addr[4] | (addr[5] << 8); + + spin_lock_irq(&tp->lock); + + RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W32(MAC0, low); + RTL_W32(MAC4, high); + RTL_W8(Cfg9346, Cfg9346_Lock); + + spin_unlock_irq(&tp->lock); +} + +static int rtl_set_mac_address(struct net_device *dev, void *p) +{ + struct rtl8169_private *tp = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + rtl_rar_set(tp, dev->dev_addr); + + return 0; +} + static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1467,15 +1448,49 @@ return -EOPNOTSUPP; } +static const struct rtl_cfg_info { + void (*hw_start)(struct net_device *); + unsigned int region; + unsigned int align; + u16 intr_event; + u16 napi_event; +} rtl_cfg_infos [] = { + [RTL_CFG_0] = { + .hw_start = rtl_hw_start_8169, + .region = 1, + .align = 0, + .intr_event = SYSErr | LinkChg | RxOverflow | + RxFIFOOver | TxErr | TxOK | RxOK | RxErr, + .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow + }, + [RTL_CFG_1] = { + .hw_start = rtl_hw_start_8168, + .region = 2, + .align = 8, + .intr_event = SYSErr | LinkChg | RxOverflow | + TxErr | TxOK | RxOK | RxErr, + .napi_event = TxErr | TxOK | RxOK | RxOverflow + }, + [RTL_CFG_2] = { + .hw_start = rtl_hw_start_8101, + .region = 2, + .align = 8, + .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | + RxFIFOOver | TxErr | TxOK | RxOK | RxErr, + .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow + } +}; + static int __devinit rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - const unsigned int region = rtl_cfg_info[ent->driver_data].region; + const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; + const unsigned int region = cfg->region; struct rtl8169_private *tp; struct net_device *dev; void __iomem *ioaddr; - unsigned int pm_cap; - int i, rc; + unsigned int i; + int rc; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", @@ -1508,20 +1523,6 @@ if (rc < 0) goto err_out_disable_2; - /* save power state before pci_enable_device overwrites it */ - pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm_cap) { - u16 pwr_command, acpi_idle_state; - - pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); - acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; - } else { - if (netif_msg_probe(tp)) { - dev_err(&pdev->dev, - "PowerManagement capability not found.\n"); - } - } - /* make sure PCI base addr 1 is MMIO */ if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { if (netif_msg_probe(tp)) { @@ -1585,7 +1586,7 @@ RTL_W8(ChipCmd, CmdReset); /* Check that the chip has finished the reset. */ - for (i = 100; i > 0; i--) { + for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; msleep_interruptible(1); @@ -1647,11 +1648,12 @@ SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops); dev->stop = rtl8169_close; dev->tx_timeout = rtl8169_tx_timeout; - dev->set_multicast_list = rtl8169_set_rx_mode; + dev->set_multicast_list = rtl_set_rx_mode; dev->watchdog_timeo = RTL8169_TX_TIMEOUT; dev->irq = pdev->irq; dev->base_addr = (unsigned long) ioaddr; dev->change_mtu = rtl8169_change_mtu; + dev->set_mac_address = rtl_set_mac_address; #ifdef CONFIG_R8169_NAPI dev->poll = rtl8169_poll; @@ -1670,7 +1672,10 @@ tp->intr_mask = 0xffff; tp->pci_dev = pdev; tp->mmio_addr = ioaddr; - tp->align = rtl_cfg_info[ent->driver_data].align; + tp->align = cfg->align; + tp->hw_start = cfg->hw_start; + tp->intr_event = cfg->intr_event; + tp->napi_event = cfg->napi_event; init_timer(&tp->timer); tp->timer.data = (unsigned long) dev; @@ -1685,15 +1690,17 @@ pci_set_drvdata(pdev, dev); if (netif_msg_probe(tp)) { + u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff; + printk(KERN_INFO "%s: %s at 0x%lx, " "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", + "XID %08x IRQ %d\n", dev->name, rtl_chip_info[tp->chipset].name, dev->base_addr, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], dev->irq); + dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq); } rtl8169_init_phy(dev, tp); @@ -1714,15 +1721,11 @@ goto out; } -static void __devexit -rtl8169_remove_one(struct pci_dev *pdev) +static void __devexit rtl8169_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - assert(dev != NULL); - assert(tp != NULL); - flush_scheduled_work(); unregister_netdev(dev); @@ -1774,7 +1777,7 @@ if (retval < 0) goto err_release_ring_2; - rtl8169_hw_start(dev); + rtl_hw_start(dev); rtl8169_request_timer(dev); @@ -1805,7 +1808,7 @@ RTL_R8(ChipCmd); } -static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp) +static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; u32 cfg = rtl8169_rx_config; @@ -1818,45 +1821,90 @@ (InterFrameGap << TxInterFrameGapShift)); } -static void rtl8169_hw_start(struct net_device *dev) +static void rtl_hw_start(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; - u16 cmd; - u32 i; + unsigned int i; /* Soft reset the chip. */ RTL_W8(ChipCmd, CmdReset); /* Check that the chip has finished the reset. */ - for (i = 100; i > 0; i--) { + for (i = 0; i < 100; i++) { if ((RTL_R8(ChipCmd) & CmdReset) == 0) break; msleep_interruptible(1); } - if (tp->mac_version == RTL_GIGA_MAC_VER_05) { - RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); - } + tp->hw_start(dev); - if (tp->mac_version == RTL_GIGA_MAC_VER_13) { - pci_write_config_word(pdev, 0x68, 0x00); - pci_write_config_word(pdev, 0x69, 0x08); + netif_start_queue(dev); +} + + +static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, + void __iomem *ioaddr) +{ + /* + * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh + * register to be written before TxDescAddrLow to work. + * Switching from MMIO to I/O access fixes the issue as well. + */ + RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32); + RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK); + RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32); + RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK); +} + +static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) +{ + u16 cmd; + + cmd = RTL_R16(CPlusCmd); + RTL_W16(CPlusCmd, cmd); + return cmd; +} + +static void rtl_set_rx_max_size(void __iomem *ioaddr) +{ + /* Low hurts. Let's disable the filtering. */ + RTL_W16(RxMaxSize, 16383); +} + +static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) +{ + struct { + u32 mac_version; + u32 clk; + u32 val; + } cfg2_info [] = { + { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd + { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, + { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe + { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } + }, *p = cfg2_info; + unsigned int i; + u32 clk; + + clk = RTL_R8(Config2) & PCI_Clock_66MHz; + for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) { + if ((p->mac_version == mac_version) && (p->clk == clk)) { + RTL_W32(0x7c, p->val); + break; + } } +} + +static void rtl_hw_start_8169(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; - /* Undocumented stuff. */ if (tp->mac_version == RTL_GIGA_MAC_VER_05) { - /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */ - if ((RTL_R8(Config2) & 0x07) & 0x01) - RTL_W32(0x7c, 0x0007ffff); - - RTL_W32(0x7c, 0x0007ff00); - - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd = cmd & 0xef; - pci_write_config_word(pdev, PCI_COMMAND, cmd); + RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); } RTL_W8(Cfg9346, Cfg9346_Unlock); @@ -1868,19 +1916,11 @@ RTL_W8(EarlyTxThres, EarlyTxThld); - /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, 16383); - - if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || - (tp->mac_version == RTL_GIGA_MAC_VER_02) || - (tp->mac_version == RTL_GIGA_MAC_VER_03) || - (tp->mac_version == RTL_GIGA_MAC_VER_04)) - rtl8169_set_rx_tx_config_registers(tp); + rtl_set_rx_max_size(ioaddr); - cmd = RTL_R16(CPlusCmd); - RTL_W16(CPlusCmd, cmd); + rtl_set_rx_tx_config_registers(tp); - tp->cp_cmd |= cmd | PCIMulRW; + tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03)) { @@ -1891,29 +1931,15 @@ RTL_W16(CPlusCmd, tp->cp_cmd); + rtl8169_set_magic_reg(ioaddr, tp->mac_version); + /* * Undocumented corner. Supposedly: * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets */ RTL_W16(IntrMitigate, 0x0000); - /* - * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh - * register to be written before TxDescAddrLow to work. - * Switching from MMIO to I/O access fixes the issue as well. - */ - RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); - RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); - RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); - RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); - - if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && - (tp->mac_version != RTL_GIGA_MAC_VER_02) && - (tp->mac_version != RTL_GIGA_MAC_VER_03) && - (tp->mac_version != RTL_GIGA_MAC_VER_04)) { - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - rtl8169_set_rx_tx_config_registers(tp); - } + rtl_set_rx_tx_desc_registers(tp, ioaddr); RTL_W8(Cfg9346, Cfg9346_Lock); @@ -1922,15 +1948,107 @@ RTL_W32(RxMissed, 0); - rtl8169_set_rx_mode(dev); + rtl_set_rx_mode(dev); /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); - netif_start_queue(dev); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); +} + +static void rtl_hw_start_8168(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + u8 ctl; + + RTL_W8(Cfg9346, Cfg9346_Unlock); + + RTL_W8(EarlyTxThres, EarlyTxThld); + + rtl_set_rx_max_size(ioaddr); + + rtl_set_rx_tx_config_registers(tp); + + tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; + + RTL_W16(CPlusCmd, tp->cp_cmd); + + /* Tx performance tweak. */ + pci_read_config_byte(pdev, 0x69, &ctl); + ctl = (ctl & ~0x70) | 0x50; + pci_write_config_byte(pdev, 0x69, ctl); + + RTL_W16(IntrMitigate, 0x5151); + + /* Work around for RxFIFO overflow. */ + if (tp->mac_version == RTL_GIGA_MAC_VER_11) { + tp->intr_event |= RxFIFOOver | PCSTimeout; + tp->intr_event &= ~RxOverflow; + } + + rtl_set_rx_tx_desc_registers(tp, ioaddr); + + RTL_W8(Cfg9346, Cfg9346_Lock); + + RTL_R8(IntrMask); + + RTL_W32(RxMissed, 0); + + rtl_set_rx_mode(dev); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); + + RTL_W16(IntrMask, tp->intr_event); +} + +static void rtl_hw_start_8101(struct net_device *dev) +{ + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + + if (tp->mac_version == RTL_GIGA_MAC_VER_13) { + pci_write_config_word(pdev, 0x68, 0x00); + pci_write_config_word(pdev, 0x69, 0x08); + } + + RTL_W8(Cfg9346, Cfg9346_Unlock); + + RTL_W8(EarlyTxThres, EarlyTxThld); + + rtl_set_rx_max_size(ioaddr); + + tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; + + RTL_W16(CPlusCmd, tp->cp_cmd); + + RTL_W16(IntrMitigate, 0x0000); + + rtl_set_rx_tx_desc_registers(tp, ioaddr); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + rtl_set_rx_tx_config_registers(tp); + + RTL_W8(Cfg9346, Cfg9346_Lock); + + RTL_R8(IntrMask); + + RTL_W32(RxMissed, 0); + + rtl_set_rx_mode(dev); + + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); + + RTL_W16(IntrMask, tp->intr_event); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) @@ -1956,7 +2074,7 @@ netif_poll_enable(dev); - rtl8169_hw_start(dev); + rtl_hw_start(dev); rtl8169_request_timer(dev); @@ -1997,38 +2115,38 @@ rtl8169_mark_to_asic(desc, rx_buf_sz); } -static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align) +static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, + struct net_device *dev, + struct RxDesc *desc, int rx_buf_sz, + unsigned int align) { struct sk_buff *skb; dma_addr_t mapping; - int ret = 0; + unsigned int pad; + + pad = align ? align : NET_IP_ALIGN; - skb = dev_alloc_skb(rx_buf_sz + align); + skb = netdev_alloc_skb(dev, rx_buf_sz + pad); if (!skb) goto err_out; - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); - *sk_buff = skb; + skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); mapping = pci_map_single(pdev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); - out: - return ret; + return skb; err_out: - ret = -ENOMEM; rtl8169_make_unusable_by_asic(desc); goto out; } static void rtl8169_rx_clear(struct rtl8169_private *tp) { - int i; + unsigned int i; for (i = 0; i < NUM_RX_DESC; i++) { if (tp->Rx_skbuff[i]) { @@ -2043,16 +2161,22 @@ { u32 cur; - for (cur = start; end - cur > 0; cur++) { - int ret, i = cur % NUM_RX_DESC; + for (cur = start; end - cur != 0; cur++) { + struct sk_buff *skb; + unsigned int i = cur % NUM_RX_DESC; + + WARN_ON((s32)(end - cur) < 0); if (tp->Rx_skbuff[i]) continue; - ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, - tp->RxDescArray + i, tp->rx_buf_sz, tp->align); - if (ret < 0) + skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, + tp->RxDescArray + i, + tp->rx_buf_sz, tp->align); + if (!skb) break; + + tp->Rx_skbuff[i] = skb; } return cur - start; } @@ -2164,14 +2288,9 @@ ret = rtl8169_open(dev); if (unlikely(ret < 0)) { - if (net_ratelimit()) { - struct rtl8169_private *tp = netdev_priv(dev); - - if (netif_msg_drv(tp)) { - printk(PFX KERN_ERR - "%s: reinit failure (status = %d)." - " Rescheduling.\n", dev->name, ret); - } + if (net_ratelimit() && netif_msg_drv(tp)) { + printk(PFX KERN_ERR "%s: reinit failure (status = %d)." + " Rescheduling.\n", dev->name, ret); } rtl8169_schedule_work(dev, rtl8169_reinit_task); } @@ -2198,16 +2317,12 @@ if (tp->dirty_rx == tp->cur_rx) { rtl8169_init_ring_indexes(tp); - rtl8169_hw_start(dev); + rtl_hw_start(dev); netif_wake_queue(dev); } else { - if (net_ratelimit()) { - struct rtl8169_private *tp = netdev_priv(dev); - - if (netif_msg_intr(tp)) { - printk(PFX KERN_EMERG - "%s: Rx buffers shortage\n", dev->name); - } + if (net_ratelimit() && netif_msg_intr(tp)) { + printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", + dev->name); } rtl8169_schedule_work(dev, rtl8169_reset_task); } @@ -2231,7 +2346,7 @@ { struct skb_shared_info *info = skb_shinfo(skb); unsigned int cur_frag, entry; - struct TxDesc *txd; + struct TxDesc * uninitialized_var(txd); entry = tp->cur_tx; for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { @@ -2344,7 +2459,7 @@ smp_wmb(); - RTL_W8(TxPoll, 0x40); /* set polling bit */ + RTL_W8(TxPoll, NPQ); /* set polling bit */ if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); @@ -2414,16 +2529,12 @@ rtl8169_schedule_work(dev, rtl8169_reinit_task); } -static void -rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl8169_tx_interrupt(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned int dirty_tx, tx_left; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); - dirty_tx = tp->dirty_tx; smp_rmb(); tx_left = tp->cur_tx - dirty_tx; @@ -2459,6 +2570,15 @@ (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { netif_wake_queue(dev); } + /* + * 8168 hack: TxPoll requests are lost when the Tx packets are + * too close. Let's kick an extra TxPoll request when a burst + * of start_xmit activity is detected (if it is not detected, + * it is slow enough). -- FR + */ + smp_rmb(); + if (tp->cur_tx != dirty_tx) + RTL_W8(TxPoll, NPQ); } } @@ -2480,38 +2600,37 @@ skb->ip_summed = CHECKSUM_NONE; } -static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align) +static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, + struct rtl8169_private *tp, int pkt_size, + dma_addr_t addr) { - int ret = -1; + struct sk_buff *skb; + bool done = false; - if (pkt_size < rx_copybreak) { - struct sk_buff *skb; + if (pkt_size >= rx_copybreak) + goto out; - skb = dev_alloc_skb(pkt_size + align); - if (skb) { - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); - eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); - *sk_buff = skb; - rtl8169_mark_to_asic(desc, rx_buf_sz); - ret = 0; - } - } - return ret; + skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN); + if (!skb) + goto out; + + pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); + skb_reserve(skb, NET_IP_ALIGN); + skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); + *sk_buff = skb; + done = true; +out: + return done; } -static int -rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) +static int rtl8169_rx_interrupt(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) { unsigned int cur_rx, rx_left; unsigned int delta, count; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); - cur_rx = tp->cur_rx; rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota); @@ -2544,9 +2663,9 @@ rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { struct sk_buff *skb = tp->Rx_skbuff[entry]; + dma_addr_t addr = le64_to_cpu(desc->addr); int pkt_size = (status & 0x00001FFF) - 4; - void (*pci_action)(struct pci_dev *, dma_addr_t, - size_t, int) = pci_dma_sync_single_for_device; + struct pci_dev *pdev = tp->pci_dev; /* * The driver does not support incoming fragmented @@ -2562,19 +2681,16 @@ rtl8169_rx_csum(skb, desc); - pci_dma_sync_single_for_cpu(tp->pci_dev, - le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - - if (rtl8169_try_rx_copy(&skb, pkt_size, desc, - tp->rx_buf_sz, tp->align)) { - pci_action = pci_unmap_single; + if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { + pci_dma_sync_single_for_device(pdev, addr, + pkt_size, PCI_DMA_FROMDEVICE); + rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + } else { + pci_unmap_single(pdev, addr, pkt_size, + PCI_DMA_FROMDEVICE); tp->Rx_skbuff[entry] = NULL; } - pci_action(tp->pci_dev, le64_to_cpu(desc->addr), - tp->rx_buf_sz, PCI_DMA_FROMDEVICE); - skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); @@ -2585,6 +2701,13 @@ tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; } + + /* Work around for AMD plateform. */ + if ((desc->opts2 & 0xfffe000) && + (tp->mac_version == RTL_GIGA_MAC_VER_05)) { + desc->opts2 = 0; + cur_rx++; + } } count = cur_rx - tp->cur_rx; @@ -2608,11 +2731,9 @@ return count; } -/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t -rtl8169_interrupt(int irq, void *dev_instance) +static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) { - struct net_device *dev = (struct net_device *) dev_instance; + struct net_device *dev = dev_instance; struct rtl8169_private *tp = netdev_priv(dev); int boguscnt = max_interrupt_work; void __iomem *ioaddr = tp->mmio_addr; @@ -2637,9 +2758,17 @@ RTL_W16(IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status); - if (!(status & rtl8169_intr_mask)) + if (!(status & tp->intr_event)) break; + /* Work around for rx fifo overflow */ + if (unlikely(status & RxFIFOOver) && + (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + netif_stop_queue(dev); + rtl8169_tx_timeout(dev); + break; + } + if (unlikely(status & SYSErr)) { rtl8169_pcierr_interrupt(dev); break; @@ -2649,21 +2778,23 @@ rtl8169_check_link_status(dev, tp, ioaddr); #ifdef CONFIG_R8169_NAPI - RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event); - tp->intr_mask = ~rtl8169_napi_event; - - if (likely(netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - else if (netif_msg_intr(tp)) { - printk(KERN_INFO "%s: interrupt %04x taken in poll\n", - dev->name, status); + if (status & tp->napi_event) { + RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); + tp->intr_mask = ~tp->napi_event; + + if (likely(netif_rx_schedule_prep(dev))) + __netif_rx_schedule(dev); + else if (netif_msg_intr(tp)) { + printk(KERN_INFO "%s: interrupt %04x in poll\n", + dev->name, status); + } } break; #else /* Rx interrupt */ - if (status & (RxOK | RxOverflow | RxFIFOOver)) { + if (status & (RxOK | RxOverflow | RxFIFOOver)) rtl8169_rx_interrupt(dev, tp, ioaddr); - } + /* Tx interrupt */ if (status & (TxOK | TxErr)) rtl8169_tx_interrupt(dev, tp, ioaddr); @@ -2707,7 +2838,7 @@ * write is safe - FR */ smp_wmb(); - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W16(IntrMask, tp->intr_event); } return (work_done >= work_to_do); @@ -2789,14 +2920,13 @@ return 0; } -static void -rtl8169_set_rx_mode(struct net_device *dev) +static void rtl_set_rx_mode(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; u32 mc_filter[2]; /* Multicast hash filter */ - int i, rx_mode; + int rx_mode; u32 tmp = 0; if (dev->flags & IFF_PROMISC) { @@ -2816,6 +2946,8 @@ mc_filter[1] = mc_filter[0] = 0xffffffff; } else { struct dev_mc_list *mclist; + unsigned int i; + rx_mode = AcceptBroadcast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0; for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; @@ -2840,10 +2972,11 @@ mc_filter[1] = 0xffffffff; } - RTL_W32(RxConfig, tmp); RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(MAR0 + 4, mc_filter[1]); + RTL_W32(RxConfig, tmp); + spin_unlock_irqrestore(&tp->lock, flags); } @@ -2931,14 +3064,12 @@ #endif }; -static int __init -rtl8169_init_module(void) +static int __init rtl8169_init_module(void) { return pci_register_driver(&rtl8169_pci_driver); } -static void __exit -rtl8169_cleanup_module(void) +static void __exit rtl8169_cleanup_module(void) { pci_unregister_driver(&rtl8169_pci_driver); } --- linux-source-2.6.22-2.6.22.orig/drivers/net/3c59x.c +++ linux-source-2.6.22-2.6.22/drivers/net/3c59x.c @@ -1555,6 +1555,7 @@ mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); + vp->mii.full_duplex = vp->full_duplex; vortex_check_media(dev, 1); } --- linux-source-2.6.22-2.6.22.orig/drivers/net/sunlance.c +++ linux-source-2.6.22-2.6.22/drivers/net/sunlance.c @@ -99,8 +99,7 @@ #include /* Used by the checksum routines */ #include #include -#include -#include +#include #include /* For tpe-link-test? setting */ #include @@ -1326,6 +1325,7 @@ struct sbus_dev *lebuffer) { static unsigned version_printed; + struct device_node *dp = sdev->ofdev.node; struct net_device *dev; struct lance_private *lp; int i; @@ -1389,54 +1389,46 @@ lp->rx = lance_rx_dvma; lp->tx = lance_tx_dvma; } - lp->busmaster_regval = prom_getintdefault(sdev->prom_node, - "busmaster-regval", - (LE_C3_BSWP | LE_C3_ACON | - LE_C3_BCON)); + lp->busmaster_regval = of_getintprop_default(dp, "busmaster-regval", + (LE_C3_BSWP | + LE_C3_ACON | + LE_C3_BCON)); lp->name = lancestr; lp->ledma = ledma; lp->burst_sizes = 0; if (lp->ledma) { - char prop[6]; + struct device_node *ledma_dp = ledma->sdev->ofdev.node; + const char *prop; unsigned int sbmask; u32 csr; /* Find burst-size property for ledma */ - lp->burst_sizes = prom_getintdefault(ledma->sdev->prom_node, - "burst-sizes", 0); + lp->burst_sizes = of_getintprop_default(ledma_dp, + "burst-sizes", 0); /* ledma may be capable of fast bursts, but sbus may not. */ - sbmask = prom_getintdefault(ledma->sdev->bus->prom_node, - "burst-sizes", DMA_BURSTBITS); + sbmask = of_getintprop_default(ledma_dp, "burst-sizes", + DMA_BURSTBITS); lp->burst_sizes &= sbmask; /* Get the cable-selection property */ - memset(prop, 0, sizeof(prop)); - prom_getstring(ledma->sdev->prom_node, "cable-selection", - prop, sizeof(prop)); - if (prop[0] == 0) { - int topnd, nd; + prop = of_get_property(ledma_dp, "cable-selection", NULL); + if (!prop || prop[0] == '\0') { + struct device_node *nd; - printk(KERN_INFO "SunLance: using auto-carrier-detection.\n"); + printk(KERN_INFO "SunLance: using " + "auto-carrier-detection.\n"); - /* Is this found at /options .attributes in all - * Prom versions? XXX - */ - topnd = prom_getchild(prom_root_node); - - nd = prom_searchsiblings(topnd, "options"); + nd = of_find_node_by_path("/options"); if (!nd) goto no_link_test; - if (!prom_node_has_property(nd, "tpe-link-test?")) + prop = of_get_property(nd, "tpe-link-test?", NULL); + if (!prop) goto no_link_test; - memset(prop, 0, sizeof(prop)); - prom_getstring(nd, "tpe-link-test?", prop, - sizeof(prop)); - if (strcmp(prop, "true")) { printk(KERN_NOTICE "SunLance: warning: overriding option " "'tpe-link-test?'\n"); --- linux-source-2.6.22-2.6.22.orig/drivers/net/mlx4/mlx4.h +++ linux-source-2.6.22-2.6.22/drivers/net/mlx4/mlx4.h @@ -38,6 +38,7 @@ #define MLX4_H #include +#include #include #include --- linux-source-2.6.22-2.6.22.orig/drivers/net/mlx4/main.c +++ linux-source-2.6.22-2.6.22/drivers/net/mlx4/main.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include --- linux-source-2.6.22-2.6.22.orig/drivers/ata/libata-eh.c +++ linux-source-2.6.22-2.6.22/drivers/ata/libata-eh.c @@ -2154,19 +2154,25 @@ WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); + /* tell ACPI we're suspending */ + rc = ata_acpi_on_suspend(ap); + if (rc) + goto out; + /* suspend */ ata_eh_freeze_port(ap); if (ap->ops->port_suspend) rc = ap->ops->port_suspend(ap, ap->pm_mesg); +out: /* report result */ spin_lock_irqsave(ap->lock, flags); ap->pflags &= ~ATA_PFLAG_PM_PENDING; if (rc == 0) ap->pflags |= ATA_PFLAG_SUSPENDED; - else + else if (ap->pflags & ATA_PFLAG_FROZEN) ata_port_schedule_eh(ap); if (ap->pm_result) { @@ -2207,6 +2213,9 @@ if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); + /* tell ACPI that we're resuming */ + ata_acpi_on_resume(ap); + /* report result */ spin_lock_irqsave(ap->lock, flags); ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); --- linux-source-2.6.22-2.6.22.orig/drivers/ata/libata.h +++ linux-source-2.6.22-2.6.22/drivers/ata/libata.h @@ -98,17 +98,15 @@ /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI -extern int ata_acpi_exec_tfs(struct ata_port *ap); -extern int ata_acpi_push_id(struct ata_device *dev); +extern void ata_acpi_associate(struct ata_host *host); +extern int ata_acpi_on_suspend(struct ata_port *ap); +extern void ata_acpi_on_resume(struct ata_port *ap); +extern int ata_acpi_on_devcfg(struct ata_device *adev); #else -static inline int ata_acpi_exec_tfs(struct ata_port *ap) -{ - return 0; -} -static inline int ata_acpi_push_id(struct ata_device *dev) -{ - return 0; -} +static inline void ata_acpi_associate(struct ata_host *host) { } +static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } +static inline void ata_acpi_on_resume(struct ata_port *ap) { } +static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } #endif /* libata-scsi.c */ --- linux-source-2.6.22-2.6.22.orig/drivers/ata/ata_piix.c +++ linux-source-2.6.22-2.6.22/drivers/ata/ata_piix.c @@ -91,6 +91,7 @@ #include #include #include +#include #define DRV_NAME "ata_piix" #define DRV_VERSION "2.11" @@ -140,6 +141,9 @@ RV = -3, /* reserved */ PIIX_AHCI_DEVICE = 6, + + /* host->flags bits */ + PIIX_HOST_BROKEN_SUSPEND = (1 << 24), }; struct piix_map_db { @@ -159,6 +163,10 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); static int ich_pata_cable_detect(struct ata_port *ap); +#ifdef CONFIG_PM +static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); +static int piix_pci_device_resume(struct pci_dev *pdev); +#endif static unsigned int in_module_init = 1; @@ -200,6 +208,9 @@ /* ICH7/7-R (i945, i975) UDMA 100*/ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + { 0x8086, 0x811A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + /* ICH8 Mobile PATA Controller */ + { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* NOTE: The following PCI ids must be kept in sync with the * list in drivers/pci/quirks.c. @@ -253,8 +264,8 @@ .probe = piix_init_one, .remove = ata_pci_remove_one, #ifdef CONFIG_PM - .suspend = ata_pci_device_suspend, - .resume = ata_pci_device_resume, + .suspend = piix_pci_device_suspend, + .resume = piix_pci_device_resume, #endif }; @@ -426,7 +437,7 @@ /* PM PS SM SS MAP */ { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ { RV, RV, RV, RV }, - { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ + { P0, P2, IDE, IDE }, /* 10b (IDE mode) */ { RV, RV, RV, RV }, }, }; @@ -579,6 +590,7 @@ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ + { 0x24CA, 0x1025, 0x003d }, /* ICH4 on Acer TM290 */ /* end marker */ { 0, } }; @@ -631,7 +643,15 @@ struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) - return -ENOENT; +/* Workaround for Intel Poulsbo chipset: + * Although a PCI quirk function is added to ~/drivers/pci/quirks.c to + * handle that, but currently, the quirk function won't work because + * Poulsbo chipset regards these "reserved" registers read 00 and wrote no + * effect + */ + if (pdev->vendor != PCI_VENDOR_ID_INTEL || + pdev->device != PCI_DEVICE_ID_INTEL_POULSBO_IDE) + return -ENOENT; return ata_std_prereset(ap, deadline); } @@ -868,6 +888,107 @@ do_pata_set_dmamode(ap, adev, 1); } +#ifdef CONFIG_PM +static struct dmi_system_id piix_broken_suspend_dmi_table[] = { + { + .ident = "TECRA M5", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), + }, + }, + { + .ident = "Satellite U200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"), + }, + }, + { + .ident = "Satellite U205", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U205"), + }, + }, + { + .ident = "Portege M500", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"), + }, + }, + { } +}; + +static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + unsigned long flags; + int rc = 0; + + rc = ata_host_suspend(host, mesg); + if (rc) + return rc; + + /* Some braindamaged ACPI suspend implementations expect the + * controller to be awake on entry; otherwise, it burns cpu + * cycles and power trying to do something to the sleeping + * beauty. + */ + if (dmi_check_system(piix_broken_suspend_dmi_table) && + mesg.event == PM_EVENT_SUSPEND) { + pci_save_state(pdev); + + /* mark its power state as "unknown", since we don't + * know if e.g. the BIOS will change its device state + * when we suspend. + */ + if (pdev->current_state == PCI_D0) + pdev->current_state = PCI_UNKNOWN; + + /* tell resume that it's waking up from broken suspend */ + spin_lock_irqsave(&host->lock, flags); + host->flags |= PIIX_HOST_BROKEN_SUSPEND; + spin_unlock_irqrestore(&host->lock, flags); + } else + ata_pci_device_do_suspend(pdev, mesg); + + return 0; +} + +static int piix_pci_device_resume(struct pci_dev *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + unsigned long flags; + int rc; + + if (host->flags & PIIX_HOST_BROKEN_SUSPEND) { + spin_lock_irqsave(&host->lock, flags); + host->flags &= ~PIIX_HOST_BROKEN_SUSPEND; + spin_unlock_irqrestore(&host->lock, flags); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + /* PCI device wasn't disabled during suspend. Use + * __pci_reenable_device() to avoid affecting the + * enable count. + */ + rc = __pci_reenable_device(pdev); + if (rc) + dev_printk(KERN_ERR, &pdev->dev, "failed to enable " + "device after resume (%d)\n", rc); + } else + rc = ata_pci_device_do_resume(pdev); + + if (rc == 0) + ata_host_resume(host); + + return rc; +} +#endif + #define AHCI_PCI_BAR 5 #define AHCI_GLOBAL_CTL 0x04 #define AHCI_ENABLE (1 << 31) --- linux-source-2.6.22-2.6.22.orig/drivers/ata/pata_scc.c +++ linux-source-2.6.22-2.6.22/drivers/ata/pata_scc.c @@ -352,6 +352,8 @@ tf->hob_lbal = in_be32(ioaddr->lbal_addr); tf->hob_lbam = in_be32(ioaddr->lbam_addr); tf->hob_lbah = in_be32(ioaddr->lbah_addr); + out_be32(ioaddr->ctl_addr, tf->ctl); + ap->last_ctl = tf->ctl; } } --- linux-source-2.6.22-2.6.22.orig/drivers/ata/sata_sil.c +++ linux-source-2.6.22-2.6.22/drivers/ata/sata_sil.c @@ -380,23 +380,19 @@ serror = sil_scr_read(ap, SCR_ERROR); sil_scr_write(ap, SCR_ERROR, serror); - /* Trigger hotplug and accumulate SError only if the - * port isn't already frozen. Otherwise, PHY events - * during hardreset makes controllers with broken SIEN - * repeat probing needlessly. + /* Sometimes spurious interrupts occur, double check + * it's PHYRDY CHG. */ - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { - ata_ehi_hotplugged(&ap->eh_info); + if (serror & SERR_PHYRDY_CHG) { ap->eh_info.serror |= serror; + goto freeze; } + if (!(bmdma2 & SIL_DMA_COMPLETE)) + return; - goto freeze; } - if (unlikely(!qc)) - goto freeze; - - if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) { + if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { /* this sometimes happens, just clear IRQ */ ata_chk_status(ap); return; --- linux-source-2.6.22-2.6.22.orig/drivers/ata/libata-core.c +++ linux-source-2.6.22-2.6.22/drivers/ata/libata-core.c @@ -89,15 +89,15 @@ module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); -static int ata_ignore_hpa = 0; +static int ata_ignore_hpa = 1; module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); -MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); +MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk, default)"); static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; module_param(ata_probe_timeout, int, 0444); MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); -int libata_noacpi = 1; +int libata_noacpi = 0; module_param_named(noacpi, libata_noacpi, int, 0444); MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set"); @@ -1845,7 +1845,8 @@ int ata_dev_configure(struct ata_device *dev) { struct ata_port *ap = dev->ap; - int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; + struct ata_eh_context *ehc = &ap->eh_context; + int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; const u16 *id = dev->id; unsigned int xfer_mask; char revbuf[7]; /* XYZ-99\0 */ @@ -1862,15 +1863,10 @@ if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); - /* set _SDD */ - rc = ata_acpi_push_id(dev); - if (rc) { - ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", - rc); - } - - /* retrieve and execute the ATA task file of _GTF */ - ata_acpi_exec_tfs(ap); + /* let ACPI work its magic */ + rc = ata_acpi_on_devcfg(dev); + if (rc) + return rc; /* print device capabilities */ if (ata_msg_probe(ap)) @@ -3580,6 +3576,7 @@ /* clear SError */ if (sata_scr_read(ap, SCR_ERROR, &serror) == 0) sata_scr_write(ap, SCR_ERROR, serror); + ap->eh_info.serror = 0; /* re-enable interrupts */ if (!ap->ops->error_handler) @@ -3798,8 +3795,10 @@ /* Drives which do spurious command completion */ { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, }, { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, }, - { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, + { "HTS722012K9A300", "DCCOC54P", ATA_HORKAGE_NONCQ, }, + { "HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, + { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ @@ -6293,6 +6292,9 @@ if (rc) return rc; + /* associate with ACPI nodes */ + ata_acpi_associate(host); + /* set cable, sata_spd_limit and report */ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; --- linux-source-2.6.22-2.6.22.orig/drivers/ata/pata_it821x.c +++ linux-source-2.6.22-2.6.22/drivers/ata/pata_it821x.c @@ -533,6 +533,10 @@ struct ata_port *ap = qc->ap; struct it821x_dev *itdev = ap->private_data; + /* Only use dma for transfers to/from the media. */ + if (qc->nbytes < 2048) + return -EOPNOTSUPP; + /* No ATAPI DMA in smart mode */ if (itdev->smart) return -EOPNOTSUPP; --- linux-source-2.6.22-2.6.22.orig/drivers/ata/pata_marvell.c +++ linux-source-2.6.22-2.6.22/drivers/ata/pata_marvell.c @@ -192,6 +192,8 @@ static const struct pci_device_id marvell_pci_tbl[] = { { PCI_DEVICE(0x11AB, 0x6101), }, + { PCI_DEVICE(0x11AB, 0x6121), }, + { PCI_DEVICE(0x11AB, 0x6123), }, { PCI_DEVICE(0x11AB, 0x6145), }, { } /* terminate list */ }; --- linux-source-2.6.22-2.6.22.orig/drivers/ata/ahci.c +++ linux-source-2.6.22-2.6.22/drivers/ata/ahci.c @@ -399,7 +399,10 @@ /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ - { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 IDE */ + { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700 AHCI */ + { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700 nraid5 */ + { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700 raid5 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ --- linux-source-2.6.22-2.6.22.orig/drivers/ata/libata-acpi.c +++ linux-source-2.6.22-2.6.22/drivers/ata/libata-acpi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "libata.h" #include @@ -24,15 +25,13 @@ #include #include -#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff) -#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */ #define NO_PORT_MULT 0xffff -#define SATA_ADR_RSVD 0xffffffff +#define SATA_ADR(root,pmp) (((root) << 16) | (pmp)) #define REGS_PER_GTF 7 -struct taskfile_array { - u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ -}; +struct ata_acpi_gtf { + u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ +} __packed; /* * Helper - belongs in the PCI layer somewhere eventually @@ -42,237 +41,230 @@ return (dev->bus == &pci_bus_type); } +static void ata_acpi_associate_sata_port(struct ata_port *ap) +{ + acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT); + + ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr); +} + +static void ata_acpi_associate_ide_port(struct ata_port *ap) +{ + int max_devices, i; + + ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no); + if (!ap->acpi_handle) + return; + + max_devices = 1; + if (ap->flags & ATA_FLAG_SLAVE_POSS) + max_devices++; + + for (i = 0; i < max_devices; i++) { + struct ata_device *dev = &ap->device[i]; + + dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); + } +} + +static void ata_acpi_handle_hotplug (struct ata_port *ap, struct kobject *kobj, + u32 event) +{ + char event_string[12]; + char *envp[] = { event_string, NULL }; + struct ata_eh_info *ehi = &ap->eh_info; + + if (event == 0 || event == 1) { + unsigned long flags; + spin_lock_irqsave(ap->lock, flags); + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + spin_unlock_irqrestore(ap->lock, flags); + } + + if (kobj) { + sprintf(event_string, "BAY_EVENT=%d", event); + kobject_uevent_env(kobj, KOBJ_CHANGE, envp); + } +} + +static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_device *dev = data; + struct kobject *kobj = NULL; + + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + + ata_acpi_handle_hotplug (dev->ap, kobj, event); +} + +static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) +{ + struct ata_port *ap = data; + + ata_acpi_handle_hotplug (ap, &ap->dev->kobj, event); +} + /** - * sata_get_dev_handle - finds acpi_handle and PCI device.function - * @dev: device to locate - * @handle: returned acpi_handle for @dev - * @pcidevfn: return PCI device.func for @dev - * - * This function is somewhat SATA-specific. Or at least the - * PATA & SATA versions of this function are different, - * so it's not entirely generic code. - * - * Returns 0 on success, <0 on error. - */ -static int sata_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) -{ - struct pci_dev *pci_dev; - acpi_integer addr; - - if (!is_pci_dev(dev)) - return -ENODEV; - - pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */ - /* Please refer to the ACPI spec for the syntax of _ADR. */ - addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); - *pcidevfn = addr; - *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); - if (!*handle) - return -ENODEV; - return 0; + * ata_acpi_associate - associate ATA host with ACPI objects + * @host: target ATA host + * + * Look up ACPI objects associated with @host and initialize + * acpi_handle fields of @host, its ports and devices accordingly. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +void ata_acpi_associate(struct ata_host *host) +{ + int i, j; + + if (!is_pci_dev(host->dev) || libata_noacpi) + return; + + host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev); + if (!host->acpi_handle) + return; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA) + ata_acpi_associate_sata_port(ap); + else + ata_acpi_associate_ide_port(ap); + + if (ap->acpi_handle) + acpi_install_notify_handler (ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_ap_notify, + ap); + + for (j = 0; j < ata_port_max_devices(ap); j++) { + struct ata_device *dev = &ap->device[j]; + + if (dev->acpi_handle) + acpi_install_notify_handler (dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_dev_notify, + dev); + } + } } /** - * pata_get_dev_handle - finds acpi_handle and PCI device.function - * @dev: device to locate - * @handle: returned acpi_handle for @dev - * @pcidevfn: return PCI device.func for @dev - * - * The PATA and SATA versions of this function are different. - * - * Returns 0 on success, <0 on error. - */ -static int pata_get_dev_handle(struct device *dev, acpi_handle *handle, - acpi_integer *pcidevfn) -{ - unsigned int bus, devnum, func; - acpi_integer addr; - acpi_handle dev_handle, parent_handle; - struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; + * ata_acpi_gtm - execute _GTM + * @ap: target ATA port + * @gtm: out parameter for _GTM result + * + * Evaluate _GTM and store the result in @gtm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. + */ +static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm) +{ + struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; + union acpi_object *out_obj; acpi_status status; - struct acpi_device_info *dinfo = NULL; - int ret = -ENODEV; - struct pci_dev *pdev; - - if (!is_pci_dev(dev)) - return -ENODEV; - - pdev = to_pci_dev(dev); - - bus = pdev->bus->number; - devnum = PCI_SLOT(pdev->devfn); - func = PCI_FUNC(pdev->devfn); - - dev_handle = DEVICE_ACPI_HANDLE(dev); - parent_handle = DEVICE_ACPI_HANDLE(dev->parent); - - status = acpi_get_object_info(parent_handle, &buffer); - if (ACPI_FAILURE(status)) - goto err; - - dinfo = buffer.pointer; - if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && - dinfo->address == bus) { - /* ACPI spec for _ADR for PCI bus: */ - addr = (acpi_integer)(devnum << 16 | func); - *pcidevfn = addr; - *handle = dev_handle; - } else { - goto err; - } - - if (!*handle) - goto err; - ret = 0; -err: - kfree(dinfo); - return ret; -} - -struct walk_info { /* can be trimmed some */ - struct device *dev; - struct acpi_device *adev; - acpi_handle handle; - acpi_integer pcidevfn; - unsigned int drivenum; - acpi_handle obj_handle; - struct ata_port *ataport; - struct ata_device *atadev; - u32 sata_adr; - int status; - char basepath[ACPI_PATHNAME_MAX]; - int basepath_len; -}; - -static acpi_status get_devices(acpi_handle handle, - u32 level, void *context, void **return_value) -{ - acpi_status status; - struct walk_info *winfo = context; - struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL}; - char *pathname; - struct acpi_buffer buffer; - struct acpi_device_info *dinfo; - - status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf); - if (status) - goto ret; - pathname = namebuf.pointer; - - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - status = acpi_get_object_info(handle, &buffer); - if (ACPI_FAILURE(status)) - goto out2; - - dinfo = buffer.pointer; - - /* find full device path name for pcidevfn */ - if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && - dinfo->address == winfo->pcidevfn) { - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - ":%s: matches pcidevfn (0x%llx)\n", - pathname, winfo->pcidevfn); - strlcpy(winfo->basepath, pathname, - sizeof(winfo->basepath)); - winfo->basepath_len = strlen(pathname); - goto out; - } - - /* if basepath is not yet known, ignore this object */ - if (!winfo->basepath_len) - goto out; - - /* if this object is in scope of basepath, maybe use it */ - if (strncmp(pathname, winfo->basepath, - winfo->basepath_len) == 0) { - if (!(dinfo->valid & ACPI_VALID_ADR)) - goto out; - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "GOT ONE: (%s) root_port = 0x%llx," - " port_num = 0x%llx\n", pathname, - SATA_ROOT_PORT(dinfo->address), - SATA_PORT_NUMBER(dinfo->address)); - /* heuristics: */ - if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT) - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, - KERN_DEBUG, "warning: don't" - " know how to handle SATA port" - " multiplier\n"); - if (SATA_ROOT_PORT(dinfo->address) == - winfo->ataport->port_no && - SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) { - if (ata_msg_probe(winfo->ataport)) - ata_dev_printk(winfo->atadev, - KERN_DEBUG, - "THIS ^^^^^ is the requested" - " SATA drive (handle = 0x%p)\n", - handle); - winfo->sata_adr = dinfo->address; - winfo->obj_handle = handle; - } + int rc = 0; + + status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output); + + rc = -ENOENT; + if (status == AE_NOT_FOUND) + goto out_free; + + rc = -EINVAL; + if (ACPI_FAILURE(status)) { + ata_port_printk(ap, KERN_ERR, + "ACPI get timing mode failed (AE 0x%x)\n", + status); + goto out_free; + } + + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER) { + ata_port_printk(ap, KERN_WARNING, + "_GTM returned unexpected object type 0x%x\n", + out_obj->type); + + goto out_free; } -out: - kfree(dinfo); -out2: - kfree(pathname); - -ret: - return status; -} - -/* Get the SATA drive _ADR object. */ -static int get_sata_adr(struct device *dev, acpi_handle handle, - acpi_integer pcidevfn, unsigned int drive, - struct ata_port *ap, - struct ata_device *atadev, u32 *dev_adr) -{ - acpi_status status; - struct walk_info *winfo; - int err = -ENOMEM; - - winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL); - if (!winfo) - goto out; - - winfo->dev = dev; - winfo->atadev = atadev; - winfo->ataport = ap; - if (acpi_bus_get_device(handle, &winfo->adev) < 0) - if (ata_msg_probe(ap)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "acpi_bus_get_device failed\n"); - winfo->handle = handle; - winfo->pcidevfn = pcidevfn; - winfo->drivenum = drive; - status = acpi_get_devices(NULL, get_devices, winfo, NULL); + if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) { + ata_port_printk(ap, KERN_ERR, + "_GTM returned invalid length %d\n", + out_obj->buffer.length); + goto out_free; + } + + memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm)); + rc = 0; + out_free: + kfree(output.pointer); + return rc; +} + +/** + * ata_acpi_stm - execute _STM + * @ap: target ATA port + * @stm: timing parameter to _STM + * + * Evaluate _STM with timing parameter @stm. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. + */ +static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm) +{ + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[3]; + + in_params[0].type = ACPI_TYPE_BUFFER; + in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); + in_params[0].buffer.pointer = (u8 *)stm; + /* Buffers for id may need byteswapping ? */ + in_params[1].type = ACPI_TYPE_BUFFER; + in_params[1].buffer.length = 512; + in_params[1].buffer.pointer = (u8 *)ap->device[0].id; + in_params[2].type = ACPI_TYPE_BUFFER; + in_params[2].buffer.length = 512; + in_params[2].buffer.pointer = (u8 *)ap->device[1].id; + + input.count = 3; + input.pointer = in_params; + + status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL); + + if (status == AE_NOT_FOUND) + return -ENOENT; if (ACPI_FAILURE(status)) { - if (ata_msg_probe(ap)) - ata_dev_printk(winfo->atadev, KERN_DEBUG, - "%s: acpi_get_devices failed\n", - __FUNCTION__); - err = -ENODEV; - } else { - *dev_adr = winfo->sata_adr; - atadev->obj_handle = winfo->obj_handle; - err = 0; + ata_port_printk(ap, KERN_ERR, + "ACPI set timing mode failed (status=0x%x)\n", status); + return -EINVAL; } - kfree(winfo); -out: - return err; + return 0; } /** - * do_drive_get_GTF - get the drive bootup default taskfile settings + * ata_dev_get_GTF - get the drive bootup default taskfile settings * @dev: target ATA device - * @gtf_length: number of bytes of _GTF data returned at @gtf_address - * @gtf_address: buffer containing _GTF taskfile arrays + * @gtf: output parameter for buffer containing _GTF taskfile arrays + * @ptr_to_free: pointer which should be freed * * This applies to both PATA and SATA drives. * @@ -282,121 +274,41 @@ * The is not known in advance, so have ACPI-CA * allocate the buffer as needed and return it, then free it later. * - * The returned @gtf_length and @gtf_address are only valid if the - * function return value is 0. + * LOCKING: + * EH context. + * + * RETURNS: + * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't + * contain valid data. -errno on other errors. */ -static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, - unsigned long *gtf_address, unsigned long *obj_loc) +static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, + void **ptr_to_free) { struct ata_port *ap = dev->ap; acpi_status status; - acpi_handle dev_handle = NULL; - acpi_handle chan_handle, drive_handle; - acpi_integer pcidevfn = 0; - u32 dev_adr; struct acpi_buffer output; union acpi_object *out_obj; - struct device *gdev = ap->host->dev; - int err = -ENODEV; - - *gtf_length = 0; - *gtf_address = 0UL; - *obj_loc = 0UL; + int rc = 0; - if (libata_noacpi) - return 0; + /* set up output buffer */ + output.length = ACPI_ALLOCATE_BUFFER; + output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", __FUNCTION__, ap->port_no); - if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: " - "ata_dev_present: %d, PORT_DISABLED: %lu\n", - __FUNCTION__, ata_dev_enabled(dev), - ap->flags & ATA_FLAG_DISABLED); - goto out; - } - - /* Don't continue if device has no _ADR method. - * _GTF is intended for known motherboard devices. */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: pata_get_dev_handle failed (%d)\n", - __FUNCTION__, err); - goto out; - } - } else { - err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: sata_get_dev_handle failed (%d\n", - __FUNCTION__, err); - goto out; - } - } - - /* Get this drive's _ADR info. if not already known. */ - if (!dev->obj_handle) { - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - /* get child objects of dev_handle == channel objects, - * + _their_ children == drive objects */ - /* channel is ap->port_no */ - chan_handle = acpi_get_child(dev_handle, - ap->port_no); - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: chan adr=%d: chan_handle=0x%p\n", - __FUNCTION__, ap->port_no, - chan_handle); - if (!chan_handle) { - err = -ENODEV; - goto out; - } - /* TBD: could also check ACPI object VALID bits */ - drive_handle = acpi_get_child(chan_handle, dev->devno); - if (!drive_handle) { - err = -ENODEV; - goto out; - } - dev_adr = dev->devno; - dev->obj_handle = drive_handle; - } else { /* for SATA mode */ - dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(gdev, dev_handle, pcidevfn, 0, - ap, dev, &dev_adr); - } - if (err < 0 || dev_adr == SATA_ADR_RSVD || - !dev->obj_handle) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: get_sata/pata_adr failed: " - "err=%d, dev_adr=%u, obj_handle=0x%p\n", - __FUNCTION__, err, dev_adr, - dev->obj_handle); - goto out; - } - } - - /* Setting up output buffer */ - output.length = ACPI_ALLOCATE_BUFFER; - output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ - /* _GTF has no input parameters */ - err = -EIO; - status = acpi_evaluate_object(dev->obj_handle, "_GTF", - NULL, &output); + status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); + if (ACPI_FAILURE(status)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: Run _GTF error: status = 0x%x\n", - __FUNCTION__, status); - goto out; + if (status != AE_NOT_FOUND) { + ata_dev_printk(dev, KERN_WARNING, + "_GTF evaluation failed (AE 0x%x)\n", + status); + rc = -EIO; + } + goto out_free; } if (!output.length || !output.pointer) { @@ -406,43 +318,39 @@ __FUNCTION__, (unsigned long long)output.length, output.pointer); - kfree(output.pointer); - goto out; + goto out_free; } out_obj = output.pointer; if (out_obj->type != ACPI_TYPE_BUFFER) { - kfree(output.pointer); - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " - "error: expected object type of " - " ACPI_TYPE_BUFFER, got 0x%x\n", - __FUNCTION__, out_obj->type); - err = -ENOENT; - goto out; - } - - if (!out_obj->buffer.length || !out_obj->buffer.pointer || - out_obj->buffer.length % REGS_PER_GTF) { - if (ata_msg_drv(ap)) - ata_dev_printk(dev, KERN_ERR, - "%s: unexpected GTF length (%d) or addr (0x%p)\n", - __FUNCTION__, out_obj->buffer.length, - out_obj->buffer.pointer); - err = -ENOENT; - goto out; - } - - *gtf_length = out_obj->buffer.length; - *gtf_address = (unsigned long)out_obj->buffer.pointer; - *obj_loc = (unsigned long)out_obj; + ata_dev_printk(dev, KERN_WARNING, + "_GTF unexpected object type 0x%x\n", + out_obj->type); + rc = -EINVAL; + goto out_free; + } + + if (out_obj->buffer.length % REGS_PER_GTF) { + ata_dev_printk(dev, KERN_WARNING, + "unexpected _GTF length (%d)\n", + out_obj->buffer.length); + rc = -EINVAL; + goto out_free; + } + + *ptr_to_free = out_obj; + *gtf = (void *)out_obj->buffer.pointer; + rc = out_obj->buffer.length / REGS_PER_GTF; + if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: returning " - "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", - __FUNCTION__, *gtf_length, *gtf_address, *obj_loc); - err = 0; -out: - return err; + "gtf=%p, gtf_count=%d, ptr_to_free=%p\n", + __FUNCTION__, *gtf, rc, *ptr_to_free); + return rc; + + out_free: + kfree(output.pointer); + return rc; } /** @@ -461,154 +369,102 @@ * function also waits for idle after writing control and before * writing the remaining registers. * - * LOCKING: TBD: - * Inherited from caller. + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ -static void taskfile_load_raw(struct ata_device *dev, - const struct taskfile_array *gtf) +static int taskfile_load_raw(struct ata_device *dev, + const struct ata_acpi_gtf *gtf) { struct ata_port *ap = dev->ap; - struct ata_taskfile tf; - unsigned int err; + struct ata_taskfile tf, rtf; + unsigned int err_mask; - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " - "%02x %02x %02x %02x %02x %02x %02x\n", - __FUNCTION__, - gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], - gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); - - if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0) - && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0) - && (gtf->tfa[6] == 0)) - return; + if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) + && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) + && (gtf->tf[6] == 0)) + return 0; ata_tf_init(dev, &tf); /* convert gtf to tf */ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ tf.protocol = ATA_PROT_NODATA; - tf.feature = gtf->tfa[0]; /* 0x1f1 */ - tf.nsect = gtf->tfa[1]; /* 0x1f2 */ - tf.lbal = gtf->tfa[2]; /* 0x1f3 */ - tf.lbam = gtf->tfa[3]; /* 0x1f4 */ - tf.lbah = gtf->tfa[4]; /* 0x1f5 */ - tf.device = gtf->tfa[5]; /* 0x1f6 */ - tf.command = gtf->tfa[6]; /* 0x1f7 */ - - err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); - if (err && ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_ERR, - "%s: ata_exec_internal failed: %u\n", - __FUNCTION__, err); -} - -/** - * do_drive_set_taskfiles - write the drive taskfile settings from _GTF - * @dev: target ATA device - * @gtf_length: total number of bytes of _GTF taskfiles - * @gtf_address: location of _GTF taskfile arrays - * - * This applies to both PATA and SATA drives. - * - * Write {gtf_address, length gtf_length} in groups of - * REGS_PER_GTF bytes. - */ -static int do_drive_set_taskfiles(struct ata_device *dev, - unsigned int gtf_length, - unsigned long gtf_address) -{ - struct ata_port *ap = dev->ap; - int err = -ENODEV; - int gtf_count = gtf_length / REGS_PER_GTF; - int ix; - struct taskfile_array *gtf; + tf.feature = gtf->tf[0]; /* 0x1f1 */ + tf.nsect = gtf->tf[1]; /* 0x1f2 */ + tf.lbal = gtf->tf[2]; /* 0x1f3 */ + tf.lbam = gtf->tf[3]; /* 0x1f4 */ + tf.lbah = gtf->tf[4]; /* 0x1f5 */ + tf.device = gtf->tf[5]; /* 0x1f6 */ + tf.command = gtf->tf[6]; /* 0x1f7 */ if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", - __FUNCTION__, ap->port_no); - - if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA)) - return 0; - - if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) - goto out; - if (!gtf_count) /* shouldn't be here */ - goto out; - - if (gtf_length % REGS_PER_GTF) { - if (ata_msg_drv(ap)) - ata_dev_printk(dev, KERN_ERR, - "%s: unexpected GTF length (%d)\n", - __FUNCTION__, gtf_length); - goto out; - } - - for (ix = 0; ix < gtf_count; ix++) { - gtf = (struct taskfile_array *) - (gtf_address + ix * REGS_PER_GTF); - - /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - taskfile_load_raw(dev, gtf); + ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd " + "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n", + tf.command, tf.feature, tf.nsect, + tf.lbal, tf.lbam, tf.lbah, tf.device); + + rtf = tf; + err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0); + if (err_mask) { + ata_dev_printk(dev, KERN_ERR, + "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " + "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n", + tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, + tf.lbah, tf.device, err_mask, rtf.command, rtf.feature); + return -EIO; } - err = 0; -out: - return err; + return 0; } /** * ata_acpi_exec_tfs - get then write drive taskfile settings - * @ap: the ata_port for the drive + * @dev: target ATA device * - * This applies to both PATA and SATA drives. + * Evaluate _GTF and excute returned taskfiles. + * + * LOCKING: + * EH context. + * + * RETURNS: + * Number of executed taskfiles on success, 0 if _GTF doesn't exist or + * doesn't contain valid data. -errno on other errors. */ -int ata_acpi_exec_tfs(struct ata_port *ap) +static int ata_acpi_exec_tfs(struct ata_device *dev) { - int ix; - int ret = 0; - unsigned int gtf_length; - unsigned long gtf_address; - unsigned long obj_loc; - - if (libata_noacpi) - return 0; - /* - * TBD - implement PATA support. For now, - * we should not run GTF on PATA devices since some - * PATA require execution of GTM/STM before GTF. - */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) - return 0; - - for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { - struct ata_device *dev = &ap->device[ix]; - - if (!ata_dev_enabled(dev)) - continue; - - ret = do_drive_get_GTF(dev, >f_length, >f_address, - &obj_loc); - if (ret < 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - "%s: get_GTF error (%d)\n", - __FUNCTION__, ret); - break; - } - - ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address); - kfree((void *)obj_loc); - if (ret < 0) { - if (ata_msg_probe(ap)) - ata_port_printk(ap, KERN_DEBUG, - "%s: set_taskfiles error (%d)\n", - __FUNCTION__, ret); - break; - } - } - - return ret; + struct ata_acpi_gtf *gtf = NULL; + void *ptr_to_free = NULL; + int gtf_count, i, rc; + + /* get taskfiles */ + rc = ata_dev_get_GTF(dev, >f, &ptr_to_free); + if (rc < 0) { + if (rc == -EINVAL) + return 0; + return rc; + } + gtf_count = rc; + + /* execute them */ + for (i = 0, rc = 0; i < gtf_count; i++) { + int tmp; + + /* ACPI errors are eventually ignored. Run till the + * end even after errors. + */ + tmp = taskfile_load_raw(dev, gtf++); + if (!rc) + rc = tmp; + } + + kfree(ptr_to_free); + + if (rc == 0) + return gtf_count; + return rc; } /** @@ -620,62 +476,25 @@ * ATM this function never returns a failure. It is an optional * method and if it fails for whatever reason, we should still * just keep going. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. */ -int ata_acpi_push_id(struct ata_device *dev) +static int ata_acpi_push_id(struct ata_device *dev) { struct ata_port *ap = dev->ap; - acpi_handle handle; - acpi_integer pcidevfn; int err; - struct device *gdev = ap->host->dev; - u32 dev_adr; acpi_status status; struct acpi_object_list input; union acpi_object in_params[1]; - if (libata_noacpi) - return 0; - if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", __FUNCTION__, dev->devno, ap->port_no); - /* Don't continue if not a SATA device. */ - if (!(ap->flags & ATA_FLAG_ACPI_SATA)) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: Not a SATA device\n", __FUNCTION__); - goto out; - } - - /* Don't continue if device has no _ADR method. - * _SDD is intended for known motherboard devices. */ - err = sata_get_dev_handle(gdev, &handle, &pcidevfn); - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: sata_get_dev_handle failed (%d\n", - __FUNCTION__, err); - goto out; - } - - /* Get this drive's _ADR info, if not already known */ - if (!dev->obj_handle) { - dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev, - &dev_adr); - if (err < 0 || dev_adr == SATA_ADR_RSVD || - !dev->obj_handle) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: get_sata_adr failed: " - "err=%d, dev_adr=%u, obj_handle=0x%p\n", - __FUNCTION__, err, dev_adr, - dev->obj_handle); - goto out; - } - } - /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ input.count = 1; @@ -687,20 +506,150 @@ /* It's OK for _SDD to be missing too. */ swap_buf_le16(dev->id, ATA_ID_WORDS); - status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL); + status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL); swap_buf_le16(dev->id, ATA_ID_WORDS); err = ACPI_FAILURE(status) ? -EIO : 0; - if (err < 0) { - if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s _SDD error: status = 0x%x\n", - __FUNCTION__, status); + if (err < 0) + ata_dev_printk(dev, KERN_WARNING, + "ACPI _SDD failed (AE 0x%x)\n", status); + + return err; +} + +/** + * ata_acpi_on_suspend - ATA ACPI hook called on suspend + * @ap: target ATA port + * + * This function is called when @ap is about to be suspended. All + * devices are already put to sleep but the port_suspend() callback + * hasn't been executed yet. Error return from this function aborts + * suspend. + * + * LOCKING: + * EH context. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int ata_acpi_on_suspend(struct ata_port *ap) +{ + unsigned long flags; + int rc; + + /* proceed iff per-port acpi_handle is valid */ + if (!ap->acpi_handle) + return 0; + BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); + + /* store timing parameters */ + rc = ata_acpi_gtm(ap, &ap->acpi_gtm); + + spin_lock_irqsave(ap->lock, flags); + if (rc == 0) + ap->pflags |= ATA_PFLAG_GTM_VALID; + else + ap->pflags &= ~ATA_PFLAG_GTM_VALID; + spin_unlock_irqrestore(ap->lock, flags); + + if (rc == -ENOENT) + rc = 0; + return rc; +} + +/** + * ata_acpi_on_resume - ATA ACPI hook called on resume + * @ap: target ATA port + * + * This function is called when @ap is resumed - right after port + * itself is resumed but before any EH action is taken. + * + * LOCKING: + * EH context. + */ +void ata_acpi_on_resume(struct ata_port *ap) +{ + int i; + + if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { + BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); + + /* restore timing parameters */ + ata_acpi_stm(ap, &ap->acpi_gtm); } - /* always return success */ -out: - return 0; + /* schedule _GTF */ + for (i = 0; i < ATA_MAX_DEVICES; i++) + ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING; } +/** + * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration + * @dev: target ATA device + * + * This function is called when @dev is about to be configured. + * IDENTIFY data might have been modified after this hook is run. + * + * LOCKING: + * EH context. + * + * RETURNS: + * Positive number if IDENTIFY data needs to be refreshed, 0 if not, + * -errno on failure. + */ +int ata_acpi_on_devcfg(struct ata_device *dev) +{ + struct ata_port *ap = dev->ap; + struct ata_eh_context *ehc = &ap->eh_context; + int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; + int rc; + + if (!dev->acpi_handle) + return 0; + + /* do we need to do _GTF? */ + if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) && + !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET))) + return 0; + + /* do _SDD if SATA */ + if (acpi_sata) { + rc = ata_acpi_push_id(dev); + if (rc) + goto acpi_err; + } + + /* do _GTF */ + rc = ata_acpi_exec_tfs(dev); + if (rc < 0) + goto acpi_err; + + dev->flags &= ~ATA_DFLAG_ACPI_PENDING; + + /* refresh IDENTIFY page if any _GTF command has been executed */ + if (rc > 0) { + rc = ata_dev_reread_id(dev, 0); + if (rc < 0) { + ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " + "after ACPI commands\n"); + return rc; + } + } + + return 0; + acpi_err: + /* let EH retry on the first failure, disable ACPI on the second */ + if (dev->flags & ATA_DFLAG_ACPI_FAILED) { + ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " + "second time, disabling (errno=%d)\n", rc); + + dev->acpi_handle = NULL; + + /* if port is working, request IDENTIFY reload and continue */ + if (!(ap->pflags & ATA_PFLAG_FROZEN)) + rc = 1; + } + dev->flags |= ATA_DFLAG_ACPI_FAILED; + return rc; +} --- linux-source-2.6.22-2.6.22.orig/drivers/ata/pata_atiixp.c +++ linux-source-2.6.22-2.6.22/drivers/ata/pata_atiixp.c @@ -285,6 +285,7 @@ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), }, { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), }, { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), }, + { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), }, { }, }; --- linux-source-2.6.22-2.6.22.orig/drivers/ata/libata-sff.c +++ linux-source-2.6.22-2.6.22/drivers/ata/libata-sff.c @@ -211,6 +211,8 @@ tf->hob_lbal = ioread8(ioaddr->lbal_addr); tf->hob_lbam = ioread8(ioaddr->lbam_addr); tf->hob_lbah = ioread8(ioaddr->lbah_addr); + iowrite8(tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; } } --- linux-source-2.6.22-2.6.22.orig/drivers/ata/pata_sis.c +++ linux-source-2.6.22-2.6.22/drivers/ata/pata_sis.c @@ -1017,6 +1017,7 @@ { PCI_VDEVICE(SI, 0x5513), }, /* SiS 5513 */ { PCI_VDEVICE(SI, 0x5518), }, /* SiS 5518 */ { PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ + { PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ { } }; --- linux-source-2.6.22-2.6.22.orig/drivers/hwmon/smsc47m1.c +++ linux-source-2.6.22-2.6.22/drivers/hwmon/smsc47m1.c @@ -585,6 +585,8 @@ if ((err = device_create_file(dev, &dev_attr_alarms))) goto error_remove_files; + if ((err = device_create_file(dev, &dev_attr_name))) + goto error_remove_files; data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { --- linux-source-2.6.22-2.6.22.orig/drivers/hwmon/hdaps.c +++ linux-source-2.6.22-2.6.22/drivers/hwmon/hdaps.c @@ -531,6 +531,9 @@ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61P"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R61"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61"), { .ident = NULL } }; --- linux-source-2.6.22-2.6.22.orig/drivers/hwmon/lm78.c +++ linux-source-2.6.22-2.6.22/drivers/hwmon/lm78.c @@ -882,7 +882,7 @@ { struct resource res = { .start = address, - .end = address + LM78_EXTENT, + .end = address + LM78_EXTENT - 1, .name = "lm78", .flags = IORESOURCE_IO, }; --- linux-source-2.6.22-2.6.22.orig/drivers/hwmon/w83781d.c +++ linux-source-2.6.22-2.6.22/drivers/hwmon/w83781d.c @@ -740,9 +740,9 @@ static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_sensor, store_sensor, 0); static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 1); static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 2); /* I2C devices get this name attribute automatically, but for ISA devices we must create it by ourselves. */ @@ -1746,7 +1746,7 @@ { struct resource res = { .start = address, - .end = address + W83781D_EXTENT, + .end = address + W83781D_EXTENT - 1, .name = "w83781d", .flags = IORESOURCE_IO, }; --- linux-source-2.6.22-2.6.22.orig/drivers/base/power/Makefile +++ linux-source-2.6.22-2.6.22/drivers/base/power/Makefile @@ -5,6 +5,6 @@ ifeq ($(CONFIG_DEBUG_DRIVER),y) EXTRA_CFLAGS += -DDEBUG endif -ifeq ($(CONFIG_PM_DEBUG),y) +ifeq ($(CONFIG_PM_VERBOSE),y) EXTRA_CFLAGS += -DDEBUG endif --- linux-source-2.6.22-2.6.22.orig/drivers/base/platform.c +++ linux-source-2.6.22-2.6.22/drivers/base/platform.c @@ -659,7 +659,7 @@ high_totalram += high_totalram - 1; mask = (((u64)high_totalram) << 32) + 0xffffffff; } - return mask & *dev->dma_mask; + return mask; } EXPORT_SYMBOL_GPL(dma_get_required_mask); #endif --- linux-source-2.6.22-2.6.22.orig/drivers/base/cpu.c +++ linux-source-2.6.22-2.6.22/drivers/base/cpu.c @@ -53,7 +53,7 @@ ret = count; return ret; } -static SYSDEV_ATTR(online, 0600, show_online, store_online); +static SYSDEV_ATTR(online, 0644, show_online, store_online); static void __devinit register_cpu_control(struct cpu *cpu) { --- linux-source-2.6.22-2.6.22.orig/drivers/block/sunvdc.c +++ linux-source-2.6.22-2.6.22/drivers/block/sunvdc.c @@ -0,0 +1,887 @@ +/* sunvdc.c: Sun LDOM Virtual Disk Client. + * + * Copyright (C) 2007 David S. Miller + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_MODULE_NAME "sunvdc" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "June 25, 2007" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("Sun LDOM virtual disk client driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +#define VDC_TX_RING_SIZE 256 + +#define WAITING_FOR_LINK_UP 0x01 +#define WAITING_FOR_TX_SPACE 0x02 +#define WAITING_FOR_GEN_CMD 0x04 +#define WAITING_FOR_ANY -1 + +struct vdc_req_entry { + struct request *req; +}; + +struct vdc_port { + struct vio_driver_state vio; + + struct gendisk *disk; + + struct vdc_completion *cmp; + + u64 req_id; + u64 seq; + struct vdc_req_entry rq_arr[VDC_TX_RING_SIZE]; + + unsigned long ring_cookies; + + u64 max_xfer_size; + u32 vdisk_block_size; + + /* The server fills these in for us in the disk attribute + * ACK packet. + */ + u64 operations; + u32 vdisk_size; + u8 vdisk_type; + + char disk_name[32]; + + struct vio_disk_geom geom; + struct vio_disk_vtoc label; +}; + +static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) +{ + return container_of(vio, struct vdc_port, vio); +} + +/* Ordered from largest major to lowest */ +static struct vio_version vdc_versions[] = { + { .major = 1, .minor = 0 }, +}; + +#define VDCBLK_NAME "vdisk" +static int vdc_major; +#define PARTITION_SHIFT 3 + +static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr) +{ + return vio_dring_avail(dr, VDC_TX_RING_SIZE); +} + +static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo) +{ + struct gendisk *disk = bdev->bd_disk; + struct vdc_port *port = disk->private_data; + + geo->heads = (u8) port->geom.num_hd; + geo->sectors = (u8) port->geom.num_sec; + geo->cylinders = port->geom.num_cyl; + + return 0; +} + +static struct block_device_operations vdc_fops = { + .owner = THIS_MODULE, + .getgeo = vdc_getgeo, +}; + +static void vdc_finish(struct vio_driver_state *vio, int err, int waiting_for) +{ + if (vio->cmp && + (waiting_for == -1 || + vio->cmp->waiting_for == waiting_for)) { + vio->cmp->err = err; + complete(&vio->cmp->com); + vio->cmp = NULL; + } +} + +static void vdc_handshake_complete(struct vio_driver_state *vio) +{ + vdc_finish(vio, 0, WAITING_FOR_LINK_UP); +} + +static int vdc_handle_unknown(struct vdc_port *port, void *arg) +{ + struct vio_msg_tag *pkt = arg; + + printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n", + pkt->type, pkt->stype, pkt->stype_env, pkt->sid); + printk(KERN_ERR PFX "Resetting connection.\n"); + + ldc_disconnect(port->vio.lp); + + return -ECONNRESET; +} + +static int vdc_send_attr(struct vio_driver_state *vio) +{ + struct vdc_port *port = to_vdc_port(vio); + struct vio_disk_attr_info pkt; + + memset(&pkt, 0, sizeof(pkt)); + + pkt.tag.type = VIO_TYPE_CTRL; + pkt.tag.stype = VIO_SUBTYPE_INFO; + pkt.tag.stype_env = VIO_ATTR_INFO; + pkt.tag.sid = vio_send_sid(vio); + + pkt.xfer_mode = VIO_DRING_MODE; + pkt.vdisk_block_size = port->vdisk_block_size; + pkt.max_xfer_size = port->max_xfer_size; + + viodbg(HS, "SEND ATTR xfer_mode[0x%x] blksz[%u] max_xfer[%lu]\n", + pkt.xfer_mode, pkt.vdisk_block_size, pkt.max_xfer_size); + + return vio_ldc_send(&port->vio, &pkt, sizeof(pkt)); +} + +static int vdc_handle_attr(struct vio_driver_state *vio, void *arg) +{ + struct vdc_port *port = to_vdc_port(vio); + struct vio_disk_attr_info *pkt = arg; + + viodbg(HS, "GOT ATTR stype[0x%x] ops[%lx] disk_size[%lu] disk_type[%x] " + "xfer_mode[0x%x] blksz[%u] max_xfer[%lu]\n", + pkt->tag.stype, pkt->operations, + pkt->vdisk_size, pkt->vdisk_type, + pkt->xfer_mode, pkt->vdisk_block_size, + pkt->max_xfer_size); + + if (pkt->tag.stype == VIO_SUBTYPE_ACK) { + switch (pkt->vdisk_type) { + case VD_DISK_TYPE_DISK: + case VD_DISK_TYPE_SLICE: + break; + + default: + printk(KERN_ERR PFX "%s: Bogus vdisk_type 0x%x\n", + vio->name, pkt->vdisk_type); + return -ECONNRESET; + } + + if (pkt->vdisk_block_size > port->vdisk_block_size) { + printk(KERN_ERR PFX "%s: BLOCK size increased " + "%u --> %u\n", + vio->name, + port->vdisk_block_size, pkt->vdisk_block_size); + return -ECONNRESET; + } + + port->operations = pkt->operations; + port->vdisk_size = pkt->vdisk_size; + port->vdisk_type = pkt->vdisk_type; + if (pkt->max_xfer_size < port->max_xfer_size) + port->max_xfer_size = pkt->max_xfer_size; + port->vdisk_block_size = pkt->vdisk_block_size; + return 0; + } else { + printk(KERN_ERR PFX "%s: Attribute NACK\n", vio->name); + + return -ECONNRESET; + } +} + +static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) +{ + int err = desc->status; + + vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); +} + +static void vdc_end_request(struct request *req, int uptodate, int num_sectors) +{ + if (end_that_request_first(req, uptodate, num_sectors)) + return; + add_disk_randomness(req->rq_disk); + end_that_request_last(req, uptodate); +} + +static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, + unsigned int index) +{ + struct vio_disk_desc *desc = vio_dring_entry(dr, index); + struct vdc_req_entry *rqe = &port->rq_arr[index]; + struct request *req; + + if (unlikely(desc->hdr.state != VIO_DESC_DONE)) + return; + + ldc_unmap(port->vio.lp, desc->cookies, desc->ncookies); + desc->hdr.state = VIO_DESC_FREE; + dr->cons = (index + 1) & (VDC_TX_RING_SIZE - 1); + + req = rqe->req; + if (req == NULL) { + vdc_end_special(port, desc); + return; + } + + rqe->req = NULL; + + vdc_end_request(req, !desc->status, desc->size >> 9); + + if (blk_queue_stopped(port->disk->queue)) + blk_start_queue(port->disk->queue); +} + +static int vdc_ack(struct vdc_port *port, void *msgbuf) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + struct vio_dring_data *pkt = msgbuf; + + if (unlikely(pkt->dring_ident != dr->ident || + pkt->start_idx != pkt->end_idx || + pkt->start_idx >= VDC_TX_RING_SIZE)) + return 0; + + vdc_end_one(port, dr, pkt->start_idx); + + return 0; +} + +static int vdc_nack(struct vdc_port *port, void *msgbuf) +{ + /* XXX Implement me XXX */ + return 0; +} + +static void vdc_event(void *arg, int event) +{ + struct vdc_port *port = arg; + struct vio_driver_state *vio = &port->vio; + unsigned long flags; + int err; + + spin_lock_irqsave(&vio->lock, flags); + + if (unlikely(event == LDC_EVENT_RESET || + event == LDC_EVENT_UP)) { + vio_link_state_change(vio, event); + spin_unlock_irqrestore(&vio->lock, flags); + return; + } + + if (unlikely(event != LDC_EVENT_DATA_READY)) { + printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); + spin_unlock_irqrestore(&vio->lock, flags); + return; + } + + err = 0; + while (1) { + union { + struct vio_msg_tag tag; + u64 raw[8]; + } msgbuf; + + err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf)); + if (unlikely(err < 0)) { + if (err == -ECONNRESET) + vio_conn_reset(vio); + break; + } + if (err == 0) + break; + viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n", + msgbuf.tag.type, + msgbuf.tag.stype, + msgbuf.tag.stype_env, + msgbuf.tag.sid); + err = vio_validate_sid(vio, &msgbuf.tag); + if (err < 0) + break; + + if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) { + if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) + err = vdc_ack(port, &msgbuf); + else if (msgbuf.tag.stype == VIO_SUBTYPE_NACK) + err = vdc_nack(port, &msgbuf); + else + err = vdc_handle_unknown(port, &msgbuf); + } else if (msgbuf.tag.type == VIO_TYPE_CTRL) { + err = vio_control_pkt_engine(vio, &msgbuf); + } else { + err = vdc_handle_unknown(port, &msgbuf); + } + if (err < 0) + break; + } + if (err < 0) + vdc_finish(&port->vio, err, WAITING_FOR_ANY); + spin_unlock_irqrestore(&vio->lock, flags); +} + +static int __vdc_tx_trigger(struct vdc_port *port) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + struct vio_dring_data hdr = { + .tag = { + .type = VIO_TYPE_DATA, + .stype = VIO_SUBTYPE_INFO, + .stype_env = VIO_DRING_DATA, + .sid = vio_send_sid(&port->vio), + }, + .dring_ident = dr->ident, + .start_idx = dr->prod, + .end_idx = dr->prod, + }; + int err, delay; + + hdr.seq = dr->snd_nxt; + delay = 1; + do { + err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr)); + if (err > 0) { + dr->snd_nxt++; + break; + } + udelay(delay); + if ((delay <<= 1) > 128) + delay = 128; + } while (err == -EAGAIN); + + return err; +} + +static int __send_request(struct request *req) +{ + struct vdc_port *port = req->rq_disk->private_data; + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + struct scatterlist sg[port->ring_cookies]; + struct vdc_req_entry *rqe; + struct vio_disk_desc *desc; + unsigned int map_perm; + int nsg, err, i; + u64 len; + u8 op; + + map_perm = LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_IO; + + if (rq_data_dir(req) == READ) { + map_perm |= LDC_MAP_W; + op = VD_OP_BREAD; + } else { + map_perm |= LDC_MAP_R; + op = VD_OP_BWRITE; + } + + nsg = blk_rq_map_sg(req->q, req, sg); + + len = 0; + for (i = 0; i < nsg; i++) + len += sg[i].length; + + if (unlikely(vdc_tx_dring_avail(dr) < 1)) { + blk_stop_queue(port->disk->queue); + err = -ENOMEM; + goto out; + } + + desc = vio_dring_cur(dr); + + err = ldc_map_sg(port->vio.lp, sg, nsg, + desc->cookies, port->ring_cookies, + map_perm); + if (err < 0) { + printk(KERN_ERR PFX "ldc_map_sg() failure, err=%d.\n", err); + return err; + } + + rqe = &port->rq_arr[dr->prod]; + rqe->req = req; + + desc->hdr.ack = VIO_ACK_ENABLE; + desc->req_id = port->req_id; + desc->operation = op; + if (port->vdisk_type == VD_DISK_TYPE_DISK) { + desc->slice = 0xff; + } else { + desc->slice = 0; + } + desc->status = ~0; + desc->offset = (req->sector << 9) / port->vdisk_block_size; + desc->size = len; + desc->ncookies = err; + + /* This has to be a non-SMP write barrier because we are writing + * to memory which is shared with the peer LDOM. + */ + wmb(); + desc->hdr.state = VIO_DESC_READY; + + err = __vdc_tx_trigger(port); + if (err < 0) { + printk(KERN_ERR PFX "vdc_tx_trigger() failure, err=%d\n", err); + } else { + port->req_id++; + dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1); + } +out: + + return err; +} + +static void do_vdc_request(request_queue_t *q) +{ + while (1) { + struct request *req = elv_next_request(q); + + if (!req) + break; + + blkdev_dequeue_request(req); + if (__send_request(req) < 0) + vdc_end_request(req, 0, req->hard_nr_sectors); + } +} + +static int generic_request(struct vdc_port *port, u8 op, void *buf, int len) +{ + struct vio_dring_state *dr; + struct vio_completion comp; + struct vio_disk_desc *desc; + unsigned int map_perm; + unsigned long flags; + int op_len, err; + void *req_buf; + + if (!(((u64)1 << ((u64)op - 1)) & port->operations)) + return -EOPNOTSUPP; + + switch (op) { + case VD_OP_BREAD: + case VD_OP_BWRITE: + default: + return -EINVAL; + + case VD_OP_FLUSH: + op_len = 0; + map_perm = 0; + break; + + case VD_OP_GET_WCE: + op_len = sizeof(u32); + map_perm = LDC_MAP_W; + break; + + case VD_OP_SET_WCE: + op_len = sizeof(u32); + map_perm = LDC_MAP_R; + break; + + case VD_OP_GET_VTOC: + op_len = sizeof(struct vio_disk_vtoc); + map_perm = LDC_MAP_W; + break; + + case VD_OP_SET_VTOC: + op_len = sizeof(struct vio_disk_vtoc); + map_perm = LDC_MAP_R; + break; + + case VD_OP_GET_DISKGEOM: + op_len = sizeof(struct vio_disk_geom); + map_perm = LDC_MAP_W; + break; + + case VD_OP_SET_DISKGEOM: + op_len = sizeof(struct vio_disk_geom); + map_perm = LDC_MAP_R; + break; + + case VD_OP_SCSICMD: + op_len = 16; + map_perm = LDC_MAP_RW; + break; + + case VD_OP_GET_DEVID: + op_len = sizeof(struct vio_disk_devid); + map_perm = LDC_MAP_W; + break; + + case VD_OP_GET_EFI: + case VD_OP_SET_EFI: + return -EOPNOTSUPP; + break; + }; + + map_perm |= LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_IO; + + op_len = (op_len + 7) & ~7; + req_buf = kzalloc(op_len, GFP_KERNEL); + if (!req_buf) + return -ENOMEM; + + if (len > op_len) + len = op_len; + + if (map_perm & LDC_MAP_R) + memcpy(req_buf, buf, len); + + spin_lock_irqsave(&port->vio.lock, flags); + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + + /* XXX If we want to use this code generically we have to + * XXX handle TX ring exhaustion etc. + */ + desc = vio_dring_cur(dr); + + err = ldc_map_single(port->vio.lp, req_buf, op_len, + desc->cookies, port->ring_cookies, + map_perm); + if (err < 0) { + spin_unlock_irqrestore(&port->vio.lock, flags); + kfree(req_buf); + return err; + } + + init_completion(&comp.com); + comp.waiting_for = WAITING_FOR_GEN_CMD; + port->vio.cmp = ∁ + + desc->hdr.ack = VIO_ACK_ENABLE; + desc->req_id = port->req_id; + desc->operation = op; + desc->slice = 0; + desc->status = ~0; + desc->offset = 0; + desc->size = op_len; + desc->ncookies = err; + + /* This has to be a non-SMP write barrier because we are writing + * to memory which is shared with the peer LDOM. + */ + wmb(); + desc->hdr.state = VIO_DESC_READY; + + err = __vdc_tx_trigger(port); + if (err >= 0) { + port->req_id++; + dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1); + spin_unlock_irqrestore(&port->vio.lock, flags); + + wait_for_completion(&comp.com); + err = comp.err; + } else { + port->vio.cmp = NULL; + spin_unlock_irqrestore(&port->vio.lock, flags); + } + + if (map_perm & LDC_MAP_W) + memcpy(buf, req_buf, len); + + kfree(req_buf); + + return err; +} + +static int __devinit vdc_alloc_tx_ring(struct vdc_port *port) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + unsigned long len, entry_size; + int ncookies; + void *dring; + + entry_size = sizeof(struct vio_disk_desc) + + (sizeof(struct ldc_trans_cookie) * port->ring_cookies); + len = (VDC_TX_RING_SIZE * entry_size); + + ncookies = VIO_MAX_RING_COOKIES; + dring = ldc_alloc_exp_dring(port->vio.lp, len, + dr->cookies, &ncookies, + (LDC_MAP_SHADOW | + LDC_MAP_DIRECT | + LDC_MAP_RW)); + if (IS_ERR(dring)) + return PTR_ERR(dring); + + dr->base = dring; + dr->entry_size = entry_size; + dr->num_entries = VDC_TX_RING_SIZE; + dr->prod = dr->cons = 0; + dr->pending = VDC_TX_RING_SIZE; + dr->ncookies = ncookies; + + return 0; +} + +static void vdc_free_tx_ring(struct vdc_port *port) +{ + struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + + if (dr->base) { + ldc_free_exp_dring(port->vio.lp, dr->base, + (dr->entry_size * dr->num_entries), + dr->cookies, dr->ncookies); + dr->base = NULL; + dr->entry_size = 0; + dr->num_entries = 0; + dr->pending = 0; + dr->ncookies = 0; + } +} + +static int probe_disk(struct vdc_port *port) +{ + struct vio_completion comp; + struct request_queue *q; + struct gendisk *g; + int err; + + init_completion(&comp.com); + comp.err = 0; + comp.waiting_for = WAITING_FOR_LINK_UP; + port->vio.cmp = ∁ + + vio_port_up(&port->vio); + + wait_for_completion(&comp.com); + if (comp.err) + return comp.err; + + err = generic_request(port, VD_OP_GET_VTOC, + &port->label, sizeof(port->label)); + if (err < 0) { + printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err); + return err; + } + + err = generic_request(port, VD_OP_GET_DISKGEOM, + &port->geom, sizeof(port->geom)); + if (err < 0) { + printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns " + "error %d\n", err); + return err; + } + + port->vdisk_size = ((u64)port->geom.num_cyl * + (u64)port->geom.num_hd * + (u64)port->geom.num_sec); + + q = blk_init_queue(do_vdc_request, &port->vio.lock); + if (!q) { + printk(KERN_ERR PFX "%s: Could not allocate queue.\n", + port->vio.name); + return -ENOMEM; + } + g = alloc_disk(1 << PARTITION_SHIFT); + if (!g) { + printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n", + port->vio.name); + blk_cleanup_queue(q); + return -ENOMEM; + } + + port->disk = g; + + blk_queue_max_hw_segments(q, port->ring_cookies); + blk_queue_max_phys_segments(q, port->ring_cookies); + blk_queue_max_sectors(q, port->max_xfer_size); + g->major = vdc_major; + g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; + strcpy(g->disk_name, port->disk_name); + + g->fops = &vdc_fops; + g->queue = q; + g->private_data = port; + g->driverfs_dev = &port->vio.vdev->dev; + + set_capacity(g, port->vdisk_size); + + printk(KERN_INFO PFX "%s: %u sectors (%u MB)\n", + g->disk_name, + port->vdisk_size, (port->vdisk_size >> (20 - 9))); + + add_disk(g); + + return 0; +} + +static struct ldc_channel_config vdc_ldc_cfg = { + .event = vdc_event, + .mtu = 64, + .mode = LDC_MODE_UNRELIABLE, +}; + +static struct vio_driver_ops vdc_vio_ops = { + .send_attr = vdc_send_attr, + .handle_attr = vdc_handle_attr, + .handshake_complete = vdc_handshake_complete, +}; + +static void print_version(void) +{ + static int version_printed; + + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); +} + +static int __devinit vdc_port_probe(struct vio_dev *vdev, + const struct vio_device_id *id) +{ + struct mdesc_handle *hp; + struct vdc_port *port; + int err; + + print_version(); + + hp = mdesc_grab(); + + err = -ENODEV; + if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { + printk(KERN_ERR PFX "Port id [%lu] too large.\n", + vdev->dev_no); + goto err_out_release_mdesc; + } + + port = kzalloc(sizeof(*port), GFP_KERNEL); + err = -ENOMEM; + if (!port) { + printk(KERN_ERR PFX "Cannot allocate vdc_port.\n"); + goto err_out_release_mdesc; + } + + if (vdev->dev_no >= 26) + snprintf(port->disk_name, sizeof(port->disk_name), + VDCBLK_NAME "%c%c", + 'a' + ((int)vdev->dev_no / 26) - 1, + 'a' + ((int)vdev->dev_no % 26)); + else + snprintf(port->disk_name, sizeof(port->disk_name), + VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26)); + + err = vio_driver_init(&port->vio, vdev, VDEV_DISK, + vdc_versions, ARRAY_SIZE(vdc_versions), + &vdc_vio_ops, port->disk_name); + if (err) + goto err_out_free_port; + + port->vdisk_block_size = 512; + port->max_xfer_size = ((128 * 1024) / port->vdisk_block_size); + port->ring_cookies = ((port->max_xfer_size * + port->vdisk_block_size) / PAGE_SIZE) + 2; + + err = vio_ldc_alloc(&port->vio, &vdc_ldc_cfg, port); + if (err) + goto err_out_free_port; + + err = vdc_alloc_tx_ring(port); + if (err) + goto err_out_free_ldc; + + err = probe_disk(port); + if (err) + goto err_out_free_tx_ring; + + dev_set_drvdata(&vdev->dev, port); + + mdesc_release(hp); + + return 0; + +err_out_free_tx_ring: + vdc_free_tx_ring(port); + +err_out_free_ldc: + vio_ldc_free(&port->vio); + +err_out_free_port: + kfree(port); + +err_out_release_mdesc: + mdesc_release(hp); + return err; +} + +static int vdc_port_remove(struct vio_dev *vdev) +{ + struct vdc_port *port = dev_get_drvdata(&vdev->dev); + + if (port) { + del_timer_sync(&port->vio.timer); + + vdc_free_tx_ring(port); + vio_ldc_free(&port->vio); + + dev_set_drvdata(&vdev->dev, NULL); + + kfree(port); + } + return 0; +} + +static struct vio_device_id vdc_port_match[] = { + { + .type = "vdc-port", + }, + {}, +}; +MODULE_DEVICE_TABLE(vio, vdc_port_match); + +static struct vio_driver vdc_port_driver = { + .id_table = vdc_port_match, + .probe = vdc_port_probe, + .remove = vdc_port_remove, + .driver = { + .name = "vdc_port", + .owner = THIS_MODULE, + } +}; + +static int __init vdc_init(void) +{ + int err; + + err = register_blkdev(0, VDCBLK_NAME); + if (err < 0) + goto out_err; + + vdc_major = err; + + err = vio_register_driver(&vdc_port_driver); + if (err) + goto out_unregister_blkdev; + + return 0; + +out_unregister_blkdev: + unregister_blkdev(vdc_major, VDCBLK_NAME); + vdc_major = 0; + +out_err: + return err; +} + +static void __exit vdc_exit(void) +{ + vio_unregister_driver(&vdc_port_driver); + unregister_blkdev(vdc_major, VDCBLK_NAME); +} + +module_init(vdc_init); +module_exit(vdc_exit); --- linux-source-2.6.22-2.6.22.orig/drivers/block/Makefile +++ linux-source-2.6.22-2.6.22/drivers/block/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o +obj-$(CONFIG_SUNVDC) += sunvdc.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o --- linux-source-2.6.22-2.6.22.orig/drivers/block/DAC960.c +++ linux-source-2.6.22-2.6.22/drivers/block/DAC960.c @@ -17,8 +17,8 @@ */ -#define DAC960_DriverVersion "2.5.48" -#define DAC960_DriverDate "14 May 2006" +#define DAC960_DriverVersion "2.5.49" +#define DAC960_DriverDate "21 Aug 2007" #include @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1165,9 +1166,9 @@ int i; - if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask)) + if (pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK)) return DAC960_Failure(Controller, "DMA mask out of range"); - Controller->BounceBufferLimit = DAC690_V1_PciDmaMask; + Controller->BounceBufferLimit = DMA_32BIT_MASK; if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) { CommandMailboxesSize = 0; @@ -1368,9 +1369,12 @@ dma_addr_t CommandMailboxDMA; DAC960_V2_CommandStatus_T CommandStatus; - if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V2_PciDmaMask)) - return DAC960_Failure(Controller, "DMA mask out of range"); - Controller->BounceBufferLimit = DAC690_V2_PciDmaMask; + if (!pci_set_dma_mask(Controller->PCIDevice, DMA_64BIT_MASK)) + Controller->BounceBufferLimit = DMA_64BIT_MASK; + else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK)) + Controller->BounceBufferLimit = DMA_32BIT_MASK; + else + return DAC960_Failure(Controller, "DMA mask out of range"); /* This is a temporary dma mapping, used only in the scope of this function */ CommandMailbox = pci_alloc_consistent(PCI_Device, --- linux-source-2.6.22-2.6.22.orig/drivers/block/DAC960.h +++ linux-source-2.6.22-2.6.22/drivers/block/DAC960.h @@ -61,13 +61,6 @@ #define DAC960_V2_MaxPhysicalDevices 272 /* - Define the pci dma mask supported by DAC960 V1 and V2 Firmware Controlers - */ - -#define DAC690_V1_PciDmaMask 0xffffffff -#define DAC690_V2_PciDmaMask 0xffffffffffffffffULL - -/* Define a 32/64 bit I/O Address data type. */ --- linux-source-2.6.22-2.6.22.orig/drivers/block/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/block/Kconfig @@ -451,6 +451,13 @@ This driver provides Support for ATA over Ethernet block devices like the Coraid EtherDrive (R) Storage Blade. +config SUNVDC + tristate "Sun Virtual Disk Client support" + depends on SUN_LDOMS + help + Support for virtual disk devices as a client under Sun + Logical Domains. + source "drivers/s390/block/Kconfig" endmenu --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/mss_core.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/mss_core.c @@ -0,0 +1,918 @@ +/* + * mss_core.c - MMC/SD/SDIO Core driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +static LIST_HEAD(mss_protocol_list); +static LIST_HEAD(mss_host_list); + +static void mss_power_up(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.vdd = host->vdd; + ios.chip_select = MSS_CS_NO_CARE; + ios.power_mode = MSS_POWER_UP; + host->ops->set_ios(host, &ios); + + msleep(1); + + ios.clock = host->f_min; + ios.power_mode = MSS_POWER_ON; + host->ops->set_ios(host, &ios); + + msleep(2); +} + +static void mss_power_off(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.clock = 0; + ios.chip_select = MSS_CS_NO_CARE; + ios.power_mode = MSS_POWER_OFF; + host->ops->set_ios(host, &ios); +} + +static void mss_idle_cards(struct mss_host *host) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.chip_select = MSS_CS_HIGH; + host->ops->set_ios(host, &ios); + msleep(1); + ios.chip_select = MSS_CS_NO_CARE; + host->ops->set_ios(host, &ios); + msleep(1); +} + +/* + * Only after card is initialized by protocol and be registed to mmc_bus, the + * state is changed to MSS_CARD_REGISTERED. + */ +static int mmc_bus_match(struct device *dev, struct device_driver *drv) +{ + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + dbg(card->slot, "bus match driver %s", drv->name); + /* when card->state is MSS_CARD_REGISTERED,it is accepted by protocol */ + if (card->prot_driver && (card->state & MSS_CARD_REGISTERED)) + return 1; + dbg(card->slot, "bus match driver %s fail", drv->name); + return 0; +} + +//static int mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) +//{ +// printk(KERN_INFO "*** HOT PLUG ***\n"); +// return 0; +//} + +static int mmc_bus_suspend(struct device * dev, pm_message_t state) +{ + int ret = 0; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + if (card->state & MSS_CARD_HANDLEIO) + return -EAGAIN; + if (card->state & MSS_CARD_SUSPENDED) + return 0; + + if (dev->driver && dev->driver->suspend) { + ret = dev->driver->suspend(dev, state);//, SUSPEND_DISABLE); + if (ret == 0) + ret = dev->driver->suspend(dev, state);//, SUSPEND_SAVE_STATE); + if (ret == 0) + ret = dev->driver->suspend(dev, state);//, SUSPEND_POWER_DOWN); + } + /* mark MSS_CARD_SUSPEND here */ + card->state |= MSS_CARD_SUSPENDED; + return ret; +} +/* + * card may be removed or replaced by another card from the mmc_bus when it is + * sleeping, and the slot may be inserted a card when it is sleeping. + * The controller resume function need to take care about it. + */ +static int mmc_bus_resume(struct device * dev) +{ + int ret = 0; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + + /* it is new instered card or replaced card */ + if (!(card->state & MSS_CARD_SUSPENDED)) + return 0; + + card->state &= ~MSS_CARD_SUSPENDED; + if (dev->driver && dev->driver->resume) { + ret = dev->driver->resume(dev);//, RESUME_POWER_ON); + if (ret == 0) + ret = dev->driver->resume(dev);//, RESUME_RESTORE_STATE); + if (ret == 0) + ret = dev->driver->resume(dev);//, RESUME_ENABLE); + } + + return ret; +} + +static struct bus_type mmc_bus_type = { + .name = "mmc_bus", + .match = mmc_bus_match, +// .hotplug = mmc_bus_hotplug, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, +}; + +static void mss_card_device_release(struct device *dev) +{ + struct mss_card *card = container_of(dev, struct mss_card, dev); + + kfree(card); +} + +static void mss_claim_host(struct mss_host *host, struct mss_card *card) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + + /* + spin_lock_irqsave(&host->lock, flags); + while (host->active_card != NULL) { + spin_unlock_irqrestore(&host->lock, flags); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&host->wq, &wait); + schedule(); + set_current_state(TASK_RUNNING); + remove_wait_queue(&host->wq, &wait); + spin_lock_irqsave(&host->lock, flags); + } + */ + + spin_lock_irqsave(&host->lock, flags); + while (host->active_card != NULL) { + set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock_irqrestore(&host->lock, flags); + add_wait_queue(&host->wq, &wait); + schedule(); + remove_wait_queue(&host->wq, &wait); + spin_lock_irqsave(&host->lock, flags); + } + set_current_state(TASK_RUNNING); + host->active_card = card; + spin_unlock_irqrestore(&host->lock, flags); +} + +static void mss_release_host(struct mss_host* host) +{ + unsigned long flags; + + BUG_ON(host->active_card == NULL); + + spin_lock_irqsave(&host->lock, flags); + host->active_card = NULL; + spin_unlock_irqrestore(&host->lock, flags); + + wake_up(&host->wq); + +} + +int mss_card_get(struct mss_card *card) +{ + if ((card->state & MSS_CARD_REMOVING) + || !(card->state & MSS_CARD_REGISTERED)) + return -ENXIO; + if (!get_device(&card->dev)) + return -ENXIO; + return 0; +} + +void mss_card_put(struct mss_card *card) +{ + put_device(&card->dev); +} + +/* + * finish handling a request. + */ +static void mss_finish_request(struct mss_request *req) +{ + struct mss_driver *drv; + struct mss_card *card = req->card; + + drv = container_of(card->dev.driver, struct mss_driver, driver); + if (drv && drv->request_done) + drv->request_done(req); +} + +/* + * Loop all the protocol in the mss_protocol_list, and find one protocol that + * can successful recognize and init the card. + */ +static int mss_attach_protocol(struct mss_card *card) +{ + struct list_head *item; + struct mss_prot_driver *pdrv = NULL; + struct mss_host *host = card->slot->host; + int ret; + + /* loop all the protocol, and find one that match the card */ + list_for_each(item, &mss_protocol_list) { + pdrv = list_entry(item, struct mss_prot_driver, node); + dbg(card->slot, "try protocol:%s", pdrv->name); + + ret = pdrv->attach_card(card); + if (ret) + continue; + dbg(card->slot, "protocol:%s allocate spec card", pdrv->name); + + mss_claim_host(host, card); + ret = pdrv->prot_entry(card, MSS_RECOGNIZE_CARD, NULL, NULL); + mss_release_host(host); + dbg(card->slot, "protocol:%s identy ret:%d, card type:%d\n", pdrv->name, ret, card->card_type); + if (ret) + continue; + switch (card->card_type) { + case MSS_MMC_CARD: + //case MSS_CE_ATA: + case MSS_SD_CARD: + case MSS_SDIO_CARD: + case MSS_COMBO_CARD: + //dbg("identified card type: %d", card_type); + goto identified; + /* + * The card can be recognized, but it deos not fit the + * controller. + */ + case MSS_UNCOMPATIBLE_CARD: + pdrv->detach_card(card); + return MSS_ERROR_NO_PROTOCOL; + /* The card can not be recognized by the protocl */ + case MSS_UNKNOWN_CARD: + pdrv->detach_card(card); + break; + default: + pdrv->detach_card(card); + printk(KERN_WARNING "protocol driver :%s return unknown value when recognize the card\n", pdrv->name); + break; + } + } + + return MSS_ERROR_NO_PROTOCOL; +identified: + card->prot_driver = pdrv; + return 0; +} + +/* Initialize card by the protocol */ +int mss_init_card(struct mss_card *card) +{ + int ret; + struct mss_host *host = card->slot->host; + + if (!card || !card->prot_driver) + return -EINVAL; + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, MSS_INIT_CARD, NULL, NULL); + mss_release_host(host); + + dbg5("return :%d", ret); + return ret; +} + +int mss_query_card(struct mss_card *card) +{ + int ret; + struct mss_host *host = card->slot->host; + + if (!card || !card->prot_driver) + return -EINVAL; + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, MSS_QUERY_CARD, NULL, NULL); + mss_release_host(host); + + return ret; +} + +static int __mss_insert_card(struct mss_card *card) +{ + int ret; + + dbg(card->slot, "attaching protocol"); + /* Step 1: Recognize the card */ + ret = mss_attach_protocol(card); + if (ret) + return ret; + + dbg(card->slot, "protocol%s attached", card->prot_driver->name); + /* Step 2, initialize the card */ + ret = mss_init_card(card); + if (ret) { + goto detach_prot; + } + + dbg(card->slot, "protocol%s inited", card->prot_driver->name); + /* Step 3, register the card to mmc bus */ + card->dev.release = mss_card_device_release; + card->dev.parent = card->slot->host->dev; + /* set bus_id and name */ + snprintf(&card->dev.bus_id[0], sizeof(card->dev.bus_id), "mmc%d%d", + card->slot->host->id, card->slot->id); + card->dev.bus = &mmc_bus_type; + + card->state |= MSS_CARD_REGISTERED; + ret = device_register(&card->dev); /* will call mss_card_probe */ + if (ret) { + ret = MSS_ERROR_REGISTER_CARD; + card->state &= ~MSS_CARD_REGISTERED; + goto detach_prot; + } + dbg(card->slot, "protocol%s registered\n", card->prot_driver->name); + return MSS_ERROR_NONE; + +detach_prot: + card->prot_driver->detach_card(card); + card->prot_driver = NULL; + return ret; +} + +/* + * After knowing a card has been inserted into the slot, this function should + * be invoked. At last, load card driver in card (done by card_driver->probe). + */ +static int mss_insert_card(struct mss_slot *slot) +{ + struct mss_card * card; + int ret; + + BUG_ON(slot->card); + dbg(slot, "card is inserting"); + card = kzalloc(sizeof(struct mss_card), GFP_KERNEL); + if (!card) + return -ENOMEM; + card->slot = slot; + slot->card = card; + + dbg(slot, "allocate card :0x%p", card); + ret = __mss_insert_card(card); + dbg(slot, "insert ret :%d", ret); + if (ret) { + dbg(slot, "free card"); + slot->card = NULL; + kfree(card); + } + return ret; +} + +static int __mss_eject_card(struct mss_card *card) +{ + card->state |= MSS_CARD_REMOVING; + + dbg(card->slot, "card state 0x%x", card->state); + + if (card->prot_driver) { + card->prot_driver->detach_card(card); + card->prot_driver = NULL; + } + if (card->state & MSS_CARD_REGISTERED) { + device_unregister(&(card->dev)); + //card->state &= ~MSS_CARD_REGISTERED; + } + + return 0; +} + +/* + * After knowing a card has been ejected from the slot, this function should + * be invoked. At last, unload card driver in card(done by card_driver->remove). + */ +static int mss_eject_card(struct mss_card *card) +{ + BUG_ON(!card); + + dbg(card->slot, "eject card 0x%x", card); + __mss_eject_card(card); + + card->slot->card = NULL; + card->slot = NULL; + //kfree(card); + + return 0; +} + +unsigned int mss_get_capacity(struct mss_card *card) +{ + int ret; + u32 cap; + + mss_claim_host(card->slot->host, card); + ret = card->prot_driver->prot_entry(card, MSS_GET_CAPACITY, NULL, &cap); + mss_release_host(card->slot->host); + dbg5("get capcacity:0x%x, ret:%d",cap, ret); + if (ret) + cap = 0; + return cap; +} + +int mss_scan_slot(struct work_struct *work) +{ + struct mss_card *card; + struct mss_host *host; + struct mss_slot *slot; + int ret = 0; + + slot = container_of(work, struct mss_slot, card_detect.work); + + card = slot->card; + host = slot->host; + + + printk("begin scan slot, id = %d card_type = %d\n", slot->id, + (card)?(card->card_type):0); + + /* slot has card in it before, and the card is resuming back */ + if (card && (card->state & MSS_CARD_SUSPENDED)) { + dbg(slot, "suspend, card state is 0x%x", card->state); + printk("suspend, card state is 0x%x", card->state); + /* card was ejected when it is suspended */ + if (host->ops->is_slot_empty + && host->ops->is_slot_empty(slot)) { + card->state |= MSS_CARD_REMOVING; + ret = MSS_ERROR_CARD_REMOVING; + } + else { + /* + * if host provides is_slot_empty, and it + * indicates that the card is in slot, then + * we try to init it. + * else, we try to init it directly. Obvisouly + * that if there is no card in the slot, the + * init will fail + */ + dbg(slot, "no is_slot_empty"); + ret = mss_init_card(card); + if (ret) + card->state |= MSS_CARD_INVALID; + } + } + else if (card && (card->state & MSS_CARD_INVALID)) { + + dbg(slot, "2222222222222"); + + card->state &= ~MSS_CARD_INVALID; + ret = mss_eject_card(card); + + if (!host->ops->is_slot_empty + || (host->ops->is_slot_empty && + !host->ops->is_slot_empty(slot))) { + ret = mss_insert_card(slot); + } + + } + /* slot has card in it before, and no suspend happens */ + else if (card && (card->state & MSS_CARD_REGISTERED)) { + dbg(slot, "33333333333"); + + dbg(slot, "register, card state is %d", card->state); + //printk("register, card state is %d", card->state); + if (host->ops->is_slot_empty) { + dbg(slot, "has is_slot_empty"); + /* card has been ejected */ + if (host->ops->is_slot_empty(slot)) + ret = mss_eject_card(card); + } + else { + /* + * We try to send the status query command. + * If card->state has set MSS_CARD_REGISRTEED, + * it indicates that the card has finished + * identification process, and it will response + * the SEND_STATUS command. + */ + dbg(slot, "no is_slot_empty"); + if (mss_query_card(card)) + /* Card has been ejected */ + ret = mss_eject_card(card); + } + } + /* slot has card in it, but the card is not registered */ + else if (card) { + /* This should never be happens, because when insert fail, we will delete the card */ + BUG(); + } + /* slot has no card in it before */ + else if (!card) { + dbg(slot, "no card in it before"); + + mss_power_off(host); + mss_power_up(host); + mss_idle_cards(host); + if (host->ops->is_slot_empty) { + /* slot is not empty */ + if (!host->ops->is_slot_empty(slot)) + ret = mss_insert_card(slot); + } + else { + /* try to insert a card */ + ret = mss_insert_card(slot); + } + } + else { + printk(KERN_ERR "Unexpected situation when scan host:%d" + ", slot:%d, card state:0x%x\n", host->id, + slot->id, card ? card->state : 0x0); + BUG(); + } + + return ret; +} + +void mss_detect_change(struct mss_host *host, unsigned long delay, unsigned int id) +{ + struct mss_slot *slot; + + slot = &host->slots[id]; + + //printk(" enter mss_detect_change(): delay = %d, id = %d, slot = 0x%xi\n", + // delay, id, slot); + + if (delay) + schedule_delayed_work(&slot->card_detect, delay); + else + schedule_work(&slot->card_detect); + + //printk("%s(): done and exit\n", __FUNCTION__); +} + +void mss_scan_host(struct mss_host *host) +{ + struct mss_slot *slot; + int i; + + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + mss_scan_slot(&slot->card_detect.work); + } +} + +void mss_force_card_remove(struct mss_card *card) +{ + mss_eject_card(card); +} + +static void mss_wait_done(struct mss_ll_request *llreq) +{ + complete(llreq->done_data); +} + +int mss_send_ll_req(struct mss_host *host, struct mss_ll_request *llreq) +{ + DECLARE_COMPLETION(complete); + + llreq->done = mss_wait_done; + llreq->done_data = &complete; + + llreq->cmd->llreq = llreq; + llreq->cmd->error = MSS_ERROR_NONE; + if (llreq->data) + llreq->cmd->data = llreq->data; +/* if (llreq->data && llreq->stop) { + llreq->stop->llreq = llreq; + llreq->stop->error = 0; + }*/ + host->ops->request(host, llreq); + wait_for_completion(&complete); +/* if (llreq->cmd->error || (llreq->stop && llreq->stop-error))*/ + + return llreq->cmd->error; +} + +int mss_send_simple_ll_req(struct mss_host *host, struct mss_ll_request *llreq, struct mss_cmd *cmd, u32 opcode, u32 arg, u32 rtype, u32 flags) +{ + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + + cmd->opcode = opcode; + cmd->arg = arg; + cmd->rtype = rtype; + cmd->flags = flags; + + llreq->cmd = cmd; + + return mss_send_ll_req(host, llreq); +} + + +/* + * add controller into mss_host_list + */ +int register_mss_host(struct mss_host *host) +{ + list_add_tail(&host->node, &mss_host_list); + return 0; +} + +/* + * delete controller from mss_controller_list + */ +void unregister_mss_host(struct mss_host *host) +{ + + list_del(&host->node); +} + +/***************************************************************************** + * + * functions for protocol driver + * + ****************************************************************************/ + +/* + * add protocol driver into mss_protocol_list + */ +int register_mss_prot_driver(struct mss_prot_driver *drv) +{ + struct list_head *item; + struct mss_host *host; + struct mss_slot *slot; + int i; + + list_add(&drv->node, &mss_protocol_list); + + list_for_each(item, &mss_host_list) { + host = list_entry(item, struct mss_host, node); + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + if (!slot->card) + mss_scan_slot(&slot->card_detect.work); + } + } + return 0; +} + +/* + * delete protocol driver from mss_protocol_list + */ +void unregister_mss_prot_driver(struct mss_prot_driver *drv) +{ + struct mss_slot *slot; + struct list_head *item; + struct mss_host *host; + int i; + + list_del(&drv->node); + + list_for_each(item, &mss_host_list) { + host = list_entry(item, struct mss_host, node); + for (i = 0; i < host->slot_num; i++) { + slot = &host->slots[i]; + if (slot->card && slot->card->prot_driver == drv) + mss_eject_card(slot->card); + } + } + +} + +/***************************************************************************** + * + * interfaces for card driver + * + ****************************************************************************/ + +/* + * register card driver onto MMC bus + */ +int register_mss_driver (struct mss_driver *drv) +{ + drv->driver.bus = &mmc_bus_type; + return driver_register(&drv->driver); /* will call card_driver->probe */ +} + +/* + * unregister card driver from MMC bus + */ +void unregister_mss_driver (struct mss_driver *drv) +{ + driver_unregister(&drv->driver); +} + +/* + * enable SDIO interrupt, used by SDIO application driver + */ +void mss_set_sdio_int(struct mss_host *host, int sdio_en) +{ + struct mss_ios ios; + + dbg5("mss_set_sdio_int = %s", (sdio_en)?"ENABLE":"DISABLE"); + memcpy(&ios, &host->ios, sizeof(ios)); + ios.sdio_int = sdio_en; + host->ops->set_ios(host, &ios); +} + +void mss_set_clock(struct mss_host *host, int clock) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + if (clock > host->f_max) + clock = host->f_max; + else if (clock < host->f_min) + clock = host->f_min; + ios.clock = clock; + host->ops->set_ios(host, &ios); +} + +void mss_set_buswidth(struct mss_host *host, int buswidth) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.bus_width = buswidth; + host->ops->set_ios(host, &ios); +} + +void mss_set_busmode(struct mss_host *host, int busmode) +{ + struct mss_ios ios; + + memcpy(&ios, &host->ios, sizeof(ios)); + ios.bus_mode = busmode; + host->ops->set_ios(host, &ios); +} + +int mss_send_request(struct mss_request *req) +{ + struct mss_host *host; + struct mss_card *card; +// unsigned long flags; + int ret; + + if (!req->card || !req->card->slot) + return -ENODEV; + card = req->card; + host = card->slot->host; + if (req->card->state & MSS_CARD_REMOVING) + return MSS_ERROR_CARD_REMOVING; + card->state |= MSS_CARD_HANDLEIO; + dbg5("claim host"); + mss_claim_host(host, card); + ret = card->prot_driver->prot_entry(card, req->action, req->arg, + req->result); + mss_release_host(host); + dbg5("release host"); + card->state &= ~MSS_CARD_HANDLEIO; + + if (ret) + req->errno = card->prot_driver->get_errno(card); + + return ret; +} + +struct mss_host * mss_alloc_host(unsigned int slot_num, unsigned int id, unsigned int private_size) +{ + struct mss_host *host; + struct mss_slot *slot; + int i = 0, size; + + printk("%s(): enter\n", __FUNCTION__); + + size = sizeof(struct mss_host) + sizeof(struct mss_slot) * slot_num + + private_size; + host = (struct mss_host *)kzalloc(size, GFP_KERNEL); + if (!host) + return NULL; + memset(host, 0x0, size); + host->id = id; + host->slot_num = slot_num; + while(i < slot_num) { + slot = &host->slots[i]; + slot->id = i; + slot->host = host; + INIT_DELAYED_WORK(&slot->card_detect, (void (*)(void *))mss_scan_slot); + i++; + } + host->private = (void *)&host->slots[slot_num]; + host->active_card = NULL; + init_waitqueue_head(&host->wq); + spin_lock_init(&host->lock); + + return host; +} + +void mss_free_host(struct mss_host *host) +{ + kfree(host); +} + +struct mss_host *mss_find_host(int id) +{ + struct list_head *pos; + struct mss_host *host; + + list_for_each(pos, &mss_host_list) { + host = list_entry(pos, struct mss_host, node); + if (host->id == id) + return host; + } + return NULL; +} + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ + +static int mss_core_driver_init(void) +{ + return bus_register(&mmc_bus_type); +} + +static void mss_core_driver_exit(void) +{ + bus_unregister(&mmc_bus_type); +} + + +EXPORT_SYMBOL_GPL(mss_detect_change); +EXPORT_SYMBOL_GPL(mss_scan_slot); +EXPORT_SYMBOL_GPL(mss_scan_host); +EXPORT_SYMBOL_GPL(mss_alloc_host); +EXPORT_SYMBOL_GPL(mss_free_host); +EXPORT_SYMBOL_GPL(mss_find_host); +EXPORT_SYMBOL_GPL(mss_force_card_remove); +EXPORT_SYMBOL_GPL(register_mss_host); +EXPORT_SYMBOL_GPL(unregister_mss_host); + +EXPORT_SYMBOL_GPL(register_mss_driver); +EXPORT_SYMBOL_GPL(unregister_mss_driver); +EXPORT_SYMBOL_GPL(mss_send_request); +EXPORT_SYMBOL_GPL(mss_get_capacity); + +EXPORT_SYMBOL_GPL(register_mss_prot_driver); +EXPORT_SYMBOL_GPL(unregister_mss_prot_driver); +EXPORT_SYMBOL_GPL(mss_send_ll_req); +EXPORT_SYMBOL_GPL(mss_send_simple_ll_req); +EXPORT_SYMBOL_GPL(mss_set_sdio_int); +EXPORT_SYMBOL_GPL(mss_set_buswidth); +EXPORT_SYMBOL_GPL(mss_set_clock); +EXPORT_SYMBOL_GPL(mss_set_busmode); +EXPORT_SYMBOL_GPL(mss_card_get); +EXPORT_SYMBOL_GPL(mss_card_put); + +module_init(mss_core_driver_init); +module_exit(mss_core_driver_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Core driver for MMC/SD/SDIO card"); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/sd_protocol.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/sd_protocol.c @@ -0,0 +1,1100 @@ +/* + * sd_protocol.c - SD protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 sd_tran_speed(u8 ts) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + dbg5("clock :%d", clock); + return clock; +} + + +static int sd_unpack_r1(struct mss_cmd *cmd, struct sd_response_r1 *r1, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + //debug(" result in r1: %d\n", request->result); + //if ( request->result ) return request->result; + + sd_card->errno = SD_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + dbg5("status 0x%x", r1->status); + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + sd_card->errno = SD_ERROR_OUT_OF_RANGE; + if (r1->status & R1_ADDRESS_ERROR) + sd_card->errno = SD_ERROR_ADDRESS; + if (r1->status & R1_BLOCK_LEN_ERROR) + sd_card->errno = SD_ERROR_BLOCK_LEN; + if (r1->status & R1_ERASE_SEQ_ERROR) + sd_card->errno = SD_ERROR_ERASE_SEQ; + if (r1->status & R1_ERASE_PARAM) + sd_card->errno = SD_ERROR_ERASE_PARAM; + if (r1->status & R1_WP_VIOLATION) + sd_card->errno = SD_ERROR_WP_VIOLATION; + if (r1->status & R1_LOCK_UNLOCK_FAILED) + sd_card->errno = SD_ERROR_LOCK_UNLOCK_FAILED; + if (r1->status & R1_COM_CRC_ERROR) + sd_card->errno = SD_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + sd_card->errno = SD_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_CARD_ECC_FAILED) + sd_card->errno = SD_ERROR_CARD_ECC_FAILED; + if (r1->status & R1_CC_ERROR) + sd_card->errno = SD_ERROR_CC; + if (r1->status & R1_ERROR) + sd_card->errno = SD_ERROR_GENERAL; + if (r1->status & R1_CID_CSD_OVERWRITE) + sd_card->errno = SD_ERROR_CID_CSD_OVERWRITE; + } + if (r1->status & R1_AKE_SEQ_ERROR) + sd_card->errno = SD_ERROR_CID_CSD_OVERWRITE; + + if (r1->cmd != cmd->opcode) + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + dbg5("command:0x%x", r1->cmd); + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r1->status) != sd_card->state ) { + dbg5("state dismatch:r1->status:%x,state:%x\n",R1_CURRENT_STATE(r1->status),sd_card->state); + sd_card->errno = SD_ERROR_STATE_MISMATCH; + } + dbg5("sd card error %d", sd_card->errno); + if (sd_card->errno) + return MSS_ERROR_RESP_UNPACK; + return 0; +} + +static int sd_unpack_r3(struct mss_cmd *cmd, struct sd_response_r3 *r3, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + r3->cmd = unstuff_bits(buf, 40, 8, 6); + r3->ocr = unstuff_bits(buf, 8, 32, 6); + dbg5("ocr=0x%x", r3->ocr); + + if (r3->cmd != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +static int sd_unpack_r6(struct mss_cmd *cmd, struct sd_response_r6 *r6, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + int errno = SD_ERROR_NONE; + + r6->cmd = unstuff_bits(buf, 40, 8, 6); + r6->rca = unstuff_bits(buf, 24, 16, 6); + r6->status = unstuff_bits(buf, 8, 16, 6); + if (R6_STATUS(r6->status)) { + if (r6->status & R6_COM_CRC_ERROR) + errno = SD_ERROR_COM_CRC; + if (r6->status & R6_ILLEGAL_COMMAND) + errno = SD_ERROR_ILLEGAL_COMMAND; + if (r6->status & R6_ERROR) + errno = SD_ERROR_CC; + } + if (r6->cmd != cmd->opcode) + errno = SD_ERROR_HEADER_MISMATCH; + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r6->status) != sd_card->state) + errno = SD_ERROR_STATE_MISMATCH; + sd_card->errno = errno; + if (errno) + return MSS_ERROR_RESP_UNPACK; + return 0 ; +} + +static int sd_unpack_cid(struct mss_cmd *cmd, struct sd_cid *cid, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + if (buf[0] != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + cid->mid = unstuff_bits(buf, 120, 8, 16); + cid->oid = unstuff_bits(buf, 104, 16, 16); + cid->pnm[0] = unstuff_bits(buf, 96, 8, 16); + cid->pnm[1] = unstuff_bits(buf, 88, 8, 16); + cid->pnm[2] = unstuff_bits(buf, 80, 8, 16); + cid->pnm[3] = unstuff_bits(buf, 72, 8, 16); + cid->pnm[4] = unstuff_bits(buf, 64, 8, 16); + cid->pnm[5] = 0; + cid->prv = unstuff_bits(buf, 56, 8, 16); + cid->psn = unstuff_bits(buf, 24, 32, 16); + cid->mdt = unstuff_bits(buf, 8, 12, 16); +/* + DEBUG(" mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d\n", + cid->mid, cid->oid, cid->pnm, + (cid->prv>>4), (cid->prv&0xf), + cid->psn, cid->mdt&&0xf, ((cid->mdt>>4)&0xff)+2000); +*/ + + return 0; +} + +static int sd_unpack_csd(struct mss_cmd *cmd, struct sd_csd *csd, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + sd_card->errno = SD_ERROR_NONE; + if (buf[0] != 0x3f) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + csd->csd_structure = unstuff_bits(buf, 126, 2, 16); + csd->taac = unstuff_bits(buf, 112, 8, 16); + csd->nsac = unstuff_bits(buf, 104, 8, 16); + csd->tran_speed = unstuff_bits(buf, 96, 8, 16); + csd->ccc = unstuff_bits(buf, 84, 12, 16); + csd->read_bl_len = unstuff_bits(buf, 80, 4, 16); + csd->read_bl_partial = unstuff_bits(buf, 79, 1, 16); + csd->write_blk_misalign = unstuff_bits(buf, 78, 1, 16); + csd->read_blk_misalign = unstuff_bits(buf, 77, 1, 16); + csd->dsr_imp = unstuff_bits(buf, 76, 1, 16); + if (csd->csd_structure == 0) { + csd->csd.csd1.c_size = unstuff_bits(buf, 62, 12, 16); + csd->csd.csd1.vdd_r_curr_min = unstuff_bits(buf, 59, 3, 16); + csd->csd.csd1.vdd_r_curr_max = unstuff_bits(buf, 56, 3, 16); + csd->csd.csd1.vdd_w_curr_min = unstuff_bits(buf, 53, 3, 16); + csd->csd.csd1.vdd_w_curr_max = unstuff_bits(buf, 50, 3, 16); + csd->csd.csd1.c_size_mult = unstuff_bits(buf, 47, 3, 16); + } + else if (csd->csd_structure == 1) { + csd->csd.csd2.c_size = unstuff_bits(buf, 48, 22, 16); + } + csd->erase_blk_en = unstuff_bits(buf, 46, 1, 16); + csd->sector_size = unstuff_bits(buf, 39, 7, 16); + csd->wp_grp_size = unstuff_bits(buf, 32, 7, 16); + csd->wp_grp_enable = unstuff_bits(buf, 31, 1, 16); + csd->r2w_factor = unstuff_bits(buf, 26, 3, 16); + csd->write_bl_len = unstuff_bits(buf, 22, 4, 16); + csd->write_bl_partial = unstuff_bits(buf, 21, 1, 16); + csd->file_format_grp = unstuff_bits(buf, 15, 1, 16); + csd->copy = unstuff_bits(buf, 14, 1, 16); + csd->perm_write_protect = unstuff_bits(buf, 13, 1, 16); + csd->tmp_write_protect = unstuff_bits(buf, 12, 1, 16); + csd->file_format = unstuff_bits(buf, 10, 2, 16); + + if (csd->csd_structure == 0) { + dbg5(" csd_structure=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n" + " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n" + " erase_blk_en=%d sector_size=%d wp_grp_size=%d wp_grp_enable=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d\n", + csd->csd_structure,csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->csd.csd1.c_size, csd->csd.csd1.vdd_r_curr_min, + csd->csd.csd1.vdd_r_curr_max, csd->csd.csd1.vdd_w_curr_min, + csd->csd.csd1.vdd_w_curr_max, csd->csd.csd1.c_size_mult, + csd->erase_blk_en,csd->sector_size, + csd->wp_grp_size, csd->wp_grp_enable, + csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format); + } + else if (csd->csd_structure == 1) { + dbg5(" csd_structure=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d\n" + " erase_blk_en=%d sector_size=%d wp_grp_size=%d wp_grp_enable=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d\n", + csd->csd_structure,csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->csd.csd2.c_size, + csd->erase_blk_en,csd->sector_size, + csd->wp_grp_size, csd->wp_grp_enable, + csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format); + } + + return 0; +} + +static int sd_unpack_swfuncstatus(char *buf, struct sw_func_status *status) +{ + int i; + + buf += 34; + for (i = 0; i < 5; i++) { + status->func_busy[i] = buf[0] << 8 | buf[1]; + buf += 2; + } + buf += 1; + for (i = 0; i <= 5; i = i + 2) { + status->group_status[i] = buf[0] & 0xFF; + status->group_status[(i + 1)] = (buf[0] >> 4) & 0xFF; + buf += 1; + } + + for (i = 0; i <= 5; i++) { + status->func_support[i] = buf[0] << 8 | buf[1]; + buf += 2; + } + + status->current_consumption = buf[0] << 8 | buf[1]; + + return 0; +} + +static int sd_unpack_r7(struct mss_cmd *cmd, struct sd_response_r7 *r7, u16 arg, struct sd_card *sd_card) +{ + u8 *buf = cmd->response; + + r7->cmd = unstuff_bits(buf, 40, 8, 6); + r7->ver = unstuff_bits(buf, 20, 20, 6); + r7->vca = unstuff_bits(buf, 16, 4, 6); + r7->pattern = unstuff_bits(buf, 8, 8, 6); + +/* if ((r7->cmd | r7->ver | r7->vca | r7->pattern) == 0) + return MSS_NO_RESPONSE;*/ + if (r7->cmd != SD_SEND_IF_COND || r7->ver != 0 + || (r7->vca | r7->pattern) != arg) { + sd_card->errno = SD_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +static int sd_unpack_scr(u8 *buf, struct sd_scr *scr) +{ + scr->scr_structure = unstuff_bits(buf, 60, 4, 8); + scr->sd_spec = unstuff_bits(buf, 56, 4, 8); + scr->data_stat_after_erase = unstuff_bits(buf, 55, 1, 8); + scr->sd_security = unstuff_bits(buf, 52, 3, 8); + scr->sd_bus_width = unstuff_bits(buf, 48, 4, 8); + scr->init = 1; + + dbg5("scr_stru:%d, spec:%d, sata:%d, security:%d, bus:%d", scr->scr_structure, scr->sd_spec, scr->data_stat_after_erase, scr->sd_security, scr->sd_bus_width); + return 0; +} + +static int sd_get_status(struct mss_card *card, int *status) +{ + struct sd_response_r1 r1; + struct sd_card *sd_card = card->prot_card; + struct mss_host *host = card->slot->host; + int clock, ret, retries = 4; + + clock = sd_tran_speed(sd_card->csd.tran_speed); + mss_set_clock(card->slot->host, clock); + while (retries--) { + dbg5("rety"); + ret = mss_send_simple_ll_req(host, &sd_card->llreq, + &sd_card->cmd, SD_SEND_STATUS, + sd_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg5("retry ret :%d", ret); + if (ret && !retries) + return ret; + else if (!ret) { + ret = sd_unpack_r1(&sd_card->cmd, &r1, sd_card); + if (ret) { + if (sd_card->errno == SD_ERROR_STATE_MISMATCH) { + sd_card->state = R1_CURRENT_STATE(r1.status); + sd_card->errno = SD_ERROR_NONE; + } + else + return ret; + } + else + break; + } + + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW || retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + } + + *status = r1.status; + + return MSS_ERROR_NONE; +} + +/** + * The blocks requested by the kernel may or may not match what we can do. + * Unfortunately, filesystems play fast and loose with block sizes, so we're + * stuck with this. + */ +static void sd_fix_request_block_len(struct mss_card *card, int action, struct mss_rw_arg *arg) +{ + u16 block_len = 0; + struct sd_card *sd_card = card->prot_card; + struct mss_host *host = card->slot->host; + + switch(action) { + case MSS_DATA_READ: + block_len = 1 << sd_card->csd.read_bl_len; + break; + case MSS_DATA_WRITE: + block_len = 1 << sd_card->csd.write_bl_len; + break; + default: + return; + } + if (host->high_capacity && (sd_card->ocr & SD_OCR_CCS)) + block_len = 512; + if (block_len < arg->block_len) { + int scale = arg->block_len / block_len; + arg->block_len = block_len; + arg->block *= scale; + arg->nob *= scale; + } +} + +static int sd_send_cmd6(struct mss_card *card, struct sw_func_status *status, int mode, u32 funcs) +{ + struct sd_response_r1 r1; + struct sd_card *sd_card = card->prot_card; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + struct mss_data *data = &sd_card->data; + struct mss_host *host= card->slot->host; + struct scatterlist sg; + char *g_buffer = sd_card->buf; + int ret; + /* Set the argumens for CMD6. */ + /* [31]: Mode + * [30:24]: reserved (all 0s) + * [23:20]: group 6 + * [19:16]: group 5 + * [15:12]: group 4 + * [11:8]: group 3 + * [7:4]: group 2 + * [3:0]: group 1 + */ + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 8; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, SD_SW_FUNC, (funcs | ((mode & 0x1) << 31)), 0, + MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 32, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + sd_unpack_swfuncstatus(g_buffer, status); + + return 0; +} + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static int sd_recognize_card(struct mss_card *card) +{ + struct sd_response_r1 r1; + struct sd_response_r3 r3; + struct sd_response_r7 r7; + int ret; + struct sd_card *sd_card = (struct sd_card *)card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + + card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + card->card_type = MSS_UNKNOWN_CARD; + + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_GO_IDLE_STATE, 0, MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + if (host->sd_spec == MSS_SD_SPEC_20) { + if (!(host->vdd & MSS_VDD_27_36)) + return MSS_ERROR_NO_PROTOCOL; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND, + 0x1AA, MSS_RESPONSE_R7, 0); + if (ret == MSS_ERROR_TIMEOUT) + goto next; + else if (ret) + return ret; + ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card); + if (!ret) { + sd_card->ver = MSS_SD_SPEC_20; + goto next; + } + else + return ret; + } +next: + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, 0, + MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + + if (r3.ocr & host->vdd) { + card->card_type = MSS_SD_CARD; + sd_card->ver = MSS_SD_SPEC_20; + } + else + card->card_type = MSS_UNCOMPATIBLE_CARD; + + return MSS_ERROR_NONE; +} + + +/** + * sd_card_init + * @dev: mss_card_device + * + * return value: 0: success, -1: failed + */ +static int sd_card_init(struct mss_card *card) +{ + struct sd_response_r1 r1; + struct sd_response_r3 r3; + struct sd_response_r6 r6; + struct sd_response_r7 r7; + struct sd_cid cid; + int ret; + struct sd_card * sd_card= (struct sd_card *)card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + int hcs = 0; + + sd_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + sd_card->rca = 0; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.bus_width = MSS_BUSWIDTH_1BIT; + ios.clock = host->f_min; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + /* + * We have to send cmd 8 to 2.0 card. It will tell the card that the + * host support 2.0 spec. + */ + if (sd_card->ver == MSS_SD_SPEC_20 && host->sd_spec == MSS_SD_SPEC_20) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_IF_COND, + 0x1AA, MSS_RESPONSE_R7, 0); + if (ret) + return ret; + ret = sd_unpack_r7(cmd, &r7, 0x1AA, sd_card); + if (ret) + return ret; + if (host->high_capacity) + hcs = 1; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SD_SEND_OP_COND, + hcs << 30 | host->vdd, MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + while (!(r3.ocr & SD_OCR_CARD_BUSY)) { + //mdelay(20); + msleep(15); + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, 0, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SD_SEND_OP_COND, hcs << 30 | host->vdd, + MSS_RESPONSE_R3, 0); + if (ret) + return ret; + ret = sd_unpack_r3(cmd, &r3, sd_card); + if (ret) + return ret; + } + memcpy(&sd_card->ocr, &r3.ocr, sizeof(r3.ocr)); + sd_card->state = CARD_STATE_READY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_ALL_SEND_CID, 0, + MSS_RESPONSE_R2_CID, 0); + if (ret) + return ret; + + memset(&cid, 0x0, sizeof(struct sd_cid)); + ret = sd_unpack_cid(cmd, &cid, sd_card); + if (ret) + return ret; + + if (sd_card->cid.mid != 0) { + if (sd_card->cid.mid != cid.mid || sd_card->cid.oid != cid.oid + || sd_card->cid.prv != cid.prv + || sd_card->cid.psn != cid.psn + || sd_card->cid.mdt != cid.mdt + || memcmp(sd_card->cid.pnm, cid.pnm, 6)) + return MSS_ERROR_MISMATCH_CARD; + + if (memcmp(&cid, &sd_card->cid, sizeof(struct sd_cid))) + return MSS_ERROR_MISMATCH_CARD; + } + else + memcpy(&sd_card->cid, &cid, sizeof(struct sd_cid)); + + sd_card->state = CARD_STATE_IDENT; + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_RELATIVE_ADDR, + 0, MSS_RESPONSE_R6, 0); + if (ret) + return ret; + ret = sd_unpack_r6(cmd, &r6, sd_card); + if (ret) + return ret; + sd_card->state = CARD_STATE_STBY; + sd_card->rca = r6.rca; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SEND_CSD, + sd_card->rca << 16, MSS_RESPONSE_R2_CSD, 0); + if (ret) + return ret; + ret = sd_unpack_csd(cmd, &sd_card->csd, sd_card); + if (ret) + return ret; + + if (host->ops->is_slot_wp && host->ops->is_slot_wp(card->slot)) + card->state |= MSS_CARD_WP; + + return MSS_ERROR_NONE; +} + +static int sd_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct sd_response_r1 r1; + struct mss_host *host = card->slot->host; + struct mss_ios ios; + int ret, retries = 4; + struct sd_card *sd_card = (struct sd_card *)card->prot_card; + struct mss_ll_request *llreq = &sd_card->llreq; + struct mss_cmd *cmd = &sd_card->cmd; + struct mss_data *data = &sd_card->data; + struct scatterlist sg; + char *g_buffer = sd_card->buf; + int status; + u32 clock; + u32 cmdarg, blklen, opcode, flags; + + dbg5("block:%d, nob:%d, blok_len:%d", arg->block, arg->nob, arg->block_len); + ret = sd_get_status(card, &status); + if (ret) + return ret; + + if (status & R1_CARD_IS_LOCKED) + return MSS_ERROR_LOCKED; + + if (action == MSS_WRITE_MEM && host->ops->is_slot_wp && + host->ops->is_slot_wp(card->slot)) + return MSS_ERROR_WP; + + if (sd_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + sd_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + } + sd_card->state = CARD_STATE_TRAN; + + sd_fix_request_block_len(card, action, arg); + + + if (!sd_card->scr.init) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_APP_CMD, + sd_card->rca << 16, MSS_RESPONSE_R1, 0); + if (ret) + return ret; + + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 8; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, SD_SEND_SCR, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 8, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (ret) + return ret; + ret = sd_unpack_scr(g_buffer, &sd_card->scr); + if (ret) + return ret; + } + if (sd_card->scr.sd_bus_width == SCR_BUSWIDTH_1BIT) { + mss_set_buswidth(host, MSS_BUSWIDTH_1BIT); + card->bus_width = MSS_BUSWIDTH_1BIT; + } + else { + if (card->bus_width == MSS_BUSWIDTH_1BIT + && host->bus_width == MSS_BUSWIDTH_4BIT) { + mss_set_buswidth(host, MSS_BUSWIDTH_4BIT); + card->bus_width = MSS_BUSWIDTH_4BIT; + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_APP_CMD, sd_card->rca << 16, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SET_BUS_WIDTH, 0x2, MSS_RESPONSE_R1, + 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + card->bus_width = MSS_BUSWIDTH_4BIT; + } + } + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + if ((sd_card->ocr & SD_OCR_CCS) && host->high_capacity) { + ios.access_mode = MSS_ACCESS_MODE_SECTOR; + cmdarg = arg->block; + blklen = 512; + } + else { + if (arg->block_len != sd_card->block_len) { + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_SET_BLOCKLEN, arg->block_len, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) + return ret; + sd_card->block_len = arg->block_len; + } + cmdarg = arg->block * arg->block_len; + blklen = arg->block_len; + } + ios.clock = sd_tran_speed(sd_card->csd.tran_speed); + host->ops->set_ios(host, &ios); + + llreq->cmd = cmd; + llreq->data = data; + +read_write_entry: + + if (arg->nob > 1) { + if (action == MSS_READ_MEM) { + opcode = SD_READ_MULTIPLE_BLOCK; + flags = MSS_DATA_READ | MSS_DATA_MULTI; + } + else { + opcode = SD_WRITE_MULTIPLE_BLOCK; + flags = MSS_DATA_WRITE | MSS_DATA_MULTI; + } + + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sd_unpack_r1(cmd, &r1, sd_card); + sd_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV : CARD_STATE_DATA; + if (ret) { + mss_send_simple_ll_req(host, llreq, cmd, + SD_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + sd_card->state = CARD_STATE_TRAN; + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW && retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, + SD_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = sd_unpack_r1(cmd, &r1, sd_card); + sd_card->state = CARD_STATE_TRAN; + if (ret && (sd_card->errno != SD_ERROR_OUT_OF_RANGE)) + return ret; + } else { + if (action == MSS_READ_MEM) { + opcode = SD_READ_SINGLE_BLOCK; + flags = MSS_DATA_READ; + } + else { + opcode = SD_WRITE_BLOCK; + flags = MSS_DATA_WRITE; + } + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sd_unpack_r1(cmd, &r1, sd_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SD_CARD_CLOCK_SLOW && retries == 1) + clock = SD_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + } + /* Deselect the card */ + /*mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, + 0, MSS_RESPONSE_NONE, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_STBY;*/ + if (ret) + return ret; + result->bytes_xfered = data->bytes_xfered; + + return MSS_ERROR_NONE; +} + +static int sd_query_function(struct mss_card *card, struct io_swfunc_request *r, struct sw_func_status *status) +{ + struct sd_card *sd_card = card->prot_card; + int i; + u32 arg = 0; + + if (card->slot->host->sd_spec != MSS_SD_SPEC_20 + || sd_card->ver != MSS_SD_SPEC_20) + return MSS_ERROR_ACTION_UNSUPPORTED; + for (i = 5; i > 0; i--) { + arg |= ((r->args[i] & 0xF) << (i << 2)); + } + return sd_send_cmd6(card, status, 0, arg); +} + +static int sd_sw_function(struct mss_card *card, struct io_swfunc_request *r) +{ + int ret, i; + u32 arg = 0; + struct sw_func_status status; + struct sd_card *sd_card = card->prot_card; + + if (card->slot->host->sd_spec != MSS_SD_SPEC_20 + || sd_card->ver != MSS_SD_SPEC_20) + return MSS_ERROR_ACTION_UNSUPPORTED; + for (i = 0; i < 6; i++) { + if (r->args[i] >= 0xF) { + goto switch_err; + } + } + /* Step 1: CMD6(mode = 0, func = 0xF(Don't Care) */ + ret = sd_send_cmd6(card, &status, 0, 0xFFFFFF); + if (ret) + goto switch_err; + + /* Step 2: Any Switch ? */ + for (i = 0; i < 6; i++) { + if (!((status.func_support[i]) & (0x1 << (r->args[i])))) + goto switch_err; + } + + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + break; + } + } + if (i == 6) + return 0; + + /* Step 3: CMD6(mode = 0, func= funcX */ + for (i = 5; i > 0; i--) { + arg |= ((r->args[i]) << (i << 2)); + } + ret = sd_send_cmd6(card, &status, 0, arg); + if (ret) + goto switch_err; + if (status.current_consumption > r->current_acceptable) { + goto switch_err; + } + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + goto switch_err; + } + } + ret = sd_send_cmd6(card, &status, 1, arg); + if (ret) + goto switch_err; + for (i = 0; i < 6; i++) { + if (status.group_status[i] != r->args[i]) { + goto switch_err; + } + } + return 0; +switch_err: + sd_card->errno = SD_ERROR_SWFUNC; + return MSS_ERROR_ACTION_UNSUPPORTED; +} +/* count by 512 bytes */ +static int sd_get_capacity(struct mss_card *card, u32 *size) +{ + struct sd_card *sd_card = card->prot_card; + int c_size = 0; + int c_size_mult = 0; + int blk_len = 0; + + if (sd_card->csd.csd_structure == 0) { + c_size = sd_card->csd.csd.csd1.c_size; + c_size_mult = sd_card->csd.csd.csd1.c_size_mult; + blk_len = sd_card->csd.read_bl_len - 9; + } + /* (csize + 1) * 512 * 1024 bytes */ + else if (sd_card->csd.csd_structure == 1) { + c_size = sd_card->csd.csd.csd2.c_size; + c_size_mult = 7; + blk_len = 2; + } + *size = (c_size + 1) << (2 + c_size_mult + blk_len); + return MSS_ERROR_NONE; +} + + + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ +static int sd_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + int ret; + u32 status; + + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_SD_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = sd_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = sd_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg || !result) + return -EINVAL; + ret = sd_read_write_entry(card, action, arg, result); + break; + /* + case MSS_LOCK_UNLOCK: + ret = sd_lock_unlock_entry(dev); + break; + */ + case MSS_SD_QUERY_FUNC: + if (!arg || !result) + return -EINVAL; + ret = sd_query_function(card, arg, result); + break; + case MSS_SD_SW_FUNC: + if (!arg) + return -EINVAL; + ret = sd_sw_function(card, arg); + break; + case MSS_QUERY_CARD: + ret = sd_get_status(card, &status); + break; + case MSS_GET_CAPACITY: + ret = sd_get_capacity(card, result); + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + return ret; +} + +static int sd_prot_attach_card(struct mss_card *card) +{ + struct sd_card *sd_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + sd_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct sd_card))) + 512, + GFP_KERNEL); + card->prot_card = sd_card; + if (sd_card) { + sd_card->buf = (char *)ALIGN32((unsigned int)&sd_card[1]); + return 0; + } + return -ENOMEM; +} + +static void sd_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int sd_prot_get_errno(struct mss_card *card) +{ + struct sd_card *sd_card = card->prot_card; + + return sd_card->errno; +} + +static struct mss_prot_driver sd_protocol = { + .name = SD_PROTOCOL, + .prot_entry = sd_prot_entry, + .attach_card = sd_prot_attach_card, + .detach_card = sd_prot_detach_card, + .get_errno = sd_prot_get_errno, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int sd_protocol_init(void) +{ + register_mss_prot_driver(&sd_protocol); + return 0; +} + +static void sd_protocol_exit(void) +{ + unregister_mss_prot_driver(&sd_protocol); +} + + +module_init(sd_protocol_init); +module_exit(sd_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SD protocol driver"); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/mss_sdhci.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/mss_sdhci.c @@ -0,0 +1,1778 @@ +/* + * mss_sdhci.c - SD Host Controller interface driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from linux/drivers/mmc/sdhci.c + * Copyright (c) 2005 Pierre Ossman + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "mss_sdhci.h" + + +#define DRIVER_NAME "sdhci" +#define BUGMAIL " " + +#define DBG(f, x...) \ + pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) + +static unsigned int debug_nodma = 0; +static unsigned int debug_forcedma = 0; +static unsigned int debug_quirks = 0; + +#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) +#define SDHCI_QUIRK_FORCE_DMA (1<<1) +/* Controller doesn't like some resets when there is no card inserted. */ +#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) +#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) + +static const struct pci_device_id pci_ids[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_VENDOR_ID_IBM, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | + SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA | + SDHCI_QUIRK_NO_CARD_NO_RESET, + }, + + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, + }, + + { /* Generic SD host controller */ + PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) + }, + + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(pci, pci_ids); + +static void sdhci_prepare_data(struct sdhci_host *, struct mss_data *); +static void sdhci_finish_data(struct sdhci_host *); + +static void sdhci_send_command(struct sdhci_host *, struct mss_cmd *); +static void sdhci_finish_command(struct sdhci_host *); + +struct proc_dir_entry *dir_sdhci = NULL; + +static inline struct sdhci_host* slot_to_host(struct mss_slot *slot) +{ + return (struct sdhci_host*)(slot->private); +} + +static inline struct sdhci_host* mss_to_host(struct mss_host *mss) +{ + return (struct sdhci_host*)(mss->private); +} + +static void sdhci_dumpregs(struct sdhci_host *host) +{ + printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); + + printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + readl(host->ioaddr + SDHCI_DMA_ADDRESS), + readw(host->ioaddr + SDHCI_HOST_VERSION)); + printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + readw(host->ioaddr + SDHCI_BLOCK_SIZE), + readw(host->ioaddr + SDHCI_BLOCK_COUNT)); + printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + readl(host->ioaddr + SDHCI_ARGUMENT), + readw(host->ioaddr + SDHCI_TRANSFER_MODE)); + printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + readl(host->ioaddr + SDHCI_PRESENT_STATE), + readb(host->ioaddr + SDHCI_HOST_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", + readb(host->ioaddr + SDHCI_POWER_CONTROL), + readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", + readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), + readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", + readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), + readl(host->ioaddr + SDHCI_INT_STATUS)); + printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_ENABLE), + readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", + readw(host->ioaddr + SDHCI_ACMD12_ERR), + readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); + printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", + readl(host->ioaddr + SDHCI_CAPABILITIES), + readl(host->ioaddr + SDHCI_MAX_CURRENT)); + + printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); +} + +#ifdef CONFIG_PROC_FS +static int sdhci_read_proc(char* page, char** start, off_t off, int count, int* eof, void* data) { +int len = 0; +struct sdhci_host *host=(struct sdhci_host *)data; + + if (host == NULL) goto done; + + len += sprintf(page+len, DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); + + len += sprintf(page+len, DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + readl(host->ioaddr + SDHCI_DMA_ADDRESS), + readw(host->ioaddr + SDHCI_HOST_VERSION)); + len += sprintf(page+len, DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + readw(host->ioaddr + SDHCI_BLOCK_SIZE), + readw(host->ioaddr + SDHCI_BLOCK_COUNT)); + len += sprintf(page+len, DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + readl(host->ioaddr + SDHCI_ARGUMENT), + readw(host->ioaddr + SDHCI_TRANSFER_MODE)); + len += sprintf(page+len, DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + readl(host->ioaddr + SDHCI_PRESENT_STATE), + readb(host->ioaddr + SDHCI_HOST_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", + readb(host->ioaddr + SDHCI_POWER_CONTROL), + readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", + readb(host->ioaddr + SDHCI_WALK_UP_CONTROL), + readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); + len += sprintf(page+len, DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", + readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), + readl(host->ioaddr + SDHCI_INT_STATUS)); + len += sprintf(page+len, DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_ENABLE), + readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + len += sprintf(page+len, DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", + readw(host->ioaddr + SDHCI_ACMD12_ERR), + readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); + len += sprintf(page+len, DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", + readl(host->ioaddr + SDHCI_CAPABILITIES), + readl(host->ioaddr + SDHCI_MAX_CURRENT)); + + len += sprintf(page+len, DRIVER_NAME ": ===========================================\n"); + +done: + *eof = 1; + return len; +} +#endif + +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +static void sdhci_reset(struct sdhci_host *host, u8 mask) +{ + unsigned long timeout; + + if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & + SDHCI_CARD_PRESENT)) + return; + } + + writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Reset 0x%x never completed.\n", (int)mask); + sdhci_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } +} + +static void sdhci_init(struct sdhci_host *host) +{ + u32 intmask; + + sdhci_reset(host, SDHCI_RESET_ALL); + + intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | + SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | + SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT | + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | + SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; + + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); +} + +static void sdhci_activate_led(struct sdhci_host *host) +{ + u8 ctrl; + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl |= SDHCI_CTRL_LED; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +static void sdhci_deactivate_led(struct sdhci_host *host) +{ + u8 ctrl; + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_LED; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +/*****************************************************************************\ + * * + * Core functions * + * * +\*****************************************************************************/ + +static inline char* sdhci_sg_to_buffer(struct sdhci_host* host) +{ + return page_address(host->cur_sg->page) + host->cur_sg->offset; +} + +static inline int sdhci_next_sg(struct sdhci_host* host) +{ + /* Skip to next SG entry. */ + host->cur_sg++; + host->num_sg--; + + /* Any entries left? */ + if (host->num_sg > 0) { + host->offset = 0; + host->remain = host->cur_sg->length; + } + + return host->num_sg; +} + +static void sdhci_read_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int size; + + + blksize = host->data->blksz; + chunk_remain = 0; + data = 0; + + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + if (chunk_remain == 0) { + data = readl(host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + size = min(host->size, host->remain); + size = min(size, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + host->size -= size; + while (size) { + *buffer = data & 0xFF; + buffer++; + data >>= 8; + size--; + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_write_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int bytes, size; + + + blksize = host->data->blksz; + chunk_remain = 4; + data = 0; + + bytes = 0; + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + size = min(host->size, host->remain); + size = min(size, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + host->size -= size; + while (size) { + data >>= 8; + data |= (u32)*buffer << 24; + buffer++; + size--; + } + + if (chunk_remain == 0) { + writel(data, host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_transfer_pio(struct sdhci_host *host) +{ + u32 mask; + + BUG_ON(!host->data); + + if (host->size == 0) + return; + + if (host->data->flags & MSS_DATA_READ) + mask = SDHCI_DATA_AVAILABLE; + else + mask = SDHCI_SPACE_AVAILABLE; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (host->data->flags & MSS_DATA_READ) + sdhci_read_block_pio(host); + else + sdhci_write_block_pio(host); + + if (host->size == 0) + break; + + BUG_ON(host->num_sg == 0); + } + + DBG("PIO transfer complete.\n"); +} + + +static void sdhci_prepare_data(struct sdhci_host *host, struct mss_data *data) +{ + u8 count; + unsigned target_timeout, current_timeout; + + WARN_ON(host->data); + + if (data == NULL) + return; + + DBG("blksz %04x blks %04x flags %08x\n", + data->blksz, data->blocks, data->flags); + DBG("tsac %d ms\n", data->timeout_ns / 1000000); + + /* Sanity checks */ + BUG_ON(data->blksz * data->blocks > 524288); + //BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + + /* timeout in us */ + target_timeout = data->timeout_ns / 1000; + + /* + * Figure out needed cycles. + * We do this in steps in order to fit inside a 32 bit int. + * The first step is the minimum timeout, which will have a + * minimum resolution of 6 bits: + * (1) 2^13*1000 > 2^22, + * (2) host->timeout_clk < 2^16 + * => + * (1) / (2) > 2^6 + */ + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < target_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + if (count >= 0xF) { + printk(KERN_WARNING "mmchost: Too large timeout requested!\n"); + count = 0xE; + } + + if (count == 0) count = 0x8; /* add by feng for SD memory timeout issue */ + writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); + + if (host->flags & SDHCI_USE_DMA) { + int count; + + count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, + (data->flags & MSS_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); + BUG_ON(count != 1); + + writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); + } else { + host->size = data->blksz * data->blocks; + + host->cur_sg = data->sg; + host->num_sg = data->sg_len; + + host->offset = 0; + host->remain = host->cur_sg->length; + } + + + /* We do not handle DMA boundaries, so set it to max (512 KiB) */ + writew(SDHCI_MAKE_BLKSZ(7, data->blksz), + host->ioaddr + SDHCI_BLOCK_SIZE); + writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT); +} + +static void sdhci_set_transfer_mode(struct sdhci_host *host, + struct mss_data *data) +{ + u16 mode; + + WARN_ON(host->data); + + if (data == NULL) + return; + + mode = SDHCI_TRNS_BLK_CNT_EN; + if (data->blocks > 1) + mode |= SDHCI_TRNS_MULTI; + if (data->flags & MSS_DATA_READ) + mode |= SDHCI_TRNS_READ; + if (host->flags & SDHCI_USE_DMA) + mode |= SDHCI_TRNS_DMA; + + writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); +} + +static void sdhci_finish_data(struct sdhci_host *host) +{ + struct mss_data *data; + struct mss_cmd *cmd; + u16 blocks; + + BUG_ON(!host->data); + BUG_ON(!host->mrq->cmd); + + data = host->data; + cmd = host->mrq->cmd; + host->data = NULL; + + if (host->flags & SDHCI_USE_DMA) { + pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, + (data->flags & MSS_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); + } + + /* + * Controller doesn't count down when in single block mode. + */ + if ((data->blocks == 1) && (cmd->error == MSS_ERROR_NONE)) + blocks = 0; + else + blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); + data->bytes_xfered = data->blksz * (data->blocks - blocks); + + if ((cmd->error == MSS_ERROR_NONE) && blocks) { + printk(KERN_ERR "mmchost: Controller signalled completion even " + "though there were blocks left. Please report this " + "to " BUGMAIL ".\n"); + cmd->error = MSS_ERROR_CRC; + } else if (host->size != 0) { + printk(KERN_ERR "mmchost: %d bytes were left untransferred. " + "Please report this to " BUGMAIL ".\n", host->size); + cmd->error = MSS_ERROR_CRC; + } + + DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); + + tasklet_schedule(&host->finish_tasklet); +} + +static void sdhci_send_command(struct sdhci_host *host, struct mss_cmd *cmd) +{ + unsigned long flags; + u32 mask; + unsigned long timeout; + + WARN_ON(host->cmd); + + DBG("Sending cmd (%x)\n", cmd->opcode); + + /* Wait max 10 ms */ + timeout = 10; + + mask = SDHCI_CMD_INHIBIT; + + if ((cmd->data != NULL) || (cmd->rtype == MSS_RESPONSE_R1B)) + mask |= SDHCI_DATA_INHIBIT; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Controller never released " + "inhibit bit(s).\n"); + sdhci_dumpregs(host); + cmd->error = MSS_ERROR_CRC; + tasklet_schedule(&host->finish_tasklet); + return; + } + timeout--; + mdelay(1); + } + + mod_timer(&host->timer, jiffies + 10 * HZ); + + host->cmd = cmd; + + sdhci_prepare_data(host, cmd->data); + + writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); + + sdhci_set_transfer_mode(host, cmd->data); + + + switch (cmd->rtype) { + case MSS_RESPONSE_NONE: + flags = SDHCI_CMD_RESP_NONE; + break; + case MSS_RESPONSE_R1: + flags = SDHCI_CMD_RESP_SHORT | SDHCI_CMD_CRC | SDHCI_CMD_INDEX; + break; + case MSS_RESPONSE_R1B: + flags = SDHCI_CMD_RESP_SHORT_BUSY | SDHCI_CMD_CRC | SDHCI_CMD_INDEX; + break; + case MSS_RESPONSE_R2_CID: + case MSS_RESPONSE_R2_CSD: + flags = SDHCI_CMD_RESP_LONG | SDHCI_CMD_CRC; + break; + case MSS_RESPONSE_R3: + flags = SDHCI_CMD_RESP_SHORT; + break; + case MSS_RESPONSE_R6: + flags = SDHCI_CMD_RESP_SHORT | SDHCI_CMD_CRC; + break; + default: + flags = SDHCI_CMD_RESP_SHORT; + } + + if (cmd->data) + flags |= SDHCI_CMD_DATA; + DBG("SEND CMD=%08X, ARG=%08X\n", + SDHCI_MAKE_CMD(cmd->opcode, flags), cmd->arg); + writew(SDHCI_MAKE_CMD(cmd->opcode, flags), + host->ioaddr + SDHCI_COMMAND); +} + +static void sdhci_finish_command(struct sdhci_host *host) +{ + int i; + u32 *rp; + + BUG_ON(host->cmd == NULL); + + if (host->cmd->rtype != MSS_RESPONSE_NONE) { + switch (host->cmd->rtype) { + case MSS_RESPONSE_R2_CID: + case MSS_RESPONSE_R2_CSD: + case MSS_RESPONSE_R3: + host->cmd->response[0] = 0x3f; + break; + case MSS_RESPONSE_R6: + case MSS_RESPONSE_R1: + case MSS_RESPONSE_R1B: + default: + host->cmd->response[0] = host->cmd->opcode; + } + rp = (u32 *)&host->cmd->response[1]; + if ((host->cmd->rtype == MSS_RESPONSE_R2_CID)|| + (host->cmd->rtype == MSS_RESPONSE_R2_CSD)) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++, rp++) { + *rp = readl(host->ioaddr + + SDHCI_RESPONSE + (3-i)*4) << 8; + if (i != 3) + *rp |= readb(host->ioaddr + + SDHCI_RESPONSE + (3-i)*4-1); + //*rp = BYTE_REVERSE(*rp); + *rp = ___arch__swab32(*rp); + } + } else { + *rp = readl(host->ioaddr + SDHCI_RESPONSE); + //*rp = BYTE_REVERSE(*rp); + *rp = ___arch__swab32(*rp); + } + } + + host->cmd->error = MSS_ERROR_NONE; + + DBG("Ending cmd (%x)\n", host->cmd->opcode); + + if (host->cmd->data) + host->data = host->cmd->data; + else + tasklet_schedule(&host->finish_tasklet); + + host->cmd = NULL; +} + +static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int div; + //u8 ctrl; + u16 clk; + unsigned long timeout; + + if (clock == host->clock) + return; + + writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); + + + /* + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + if (clock > 25000000) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + */ + + if (clock == 0) + goto out; + + for (div = 1;div < 256;div *= 2) { + if ((host->max_clk / div) <= clock) + break; + } + div >>= 1; + + clk = div << SDHCI_DIVIDER_SHIFT; + clk |= SDHCI_CLOCK_INT_EN; + writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + + /* Wait max 10 ms */ + timeout = 10; + while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + printk(KERN_ERR "mmchost: Internal clock never estabilised.\n"); + sdhci_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } + + clk |= SDHCI_CLOCK_CARD_EN; + writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + +out: + host->clock = clock; +} + +static void sdhci_set_power(struct sdhci_host *host, unsigned short power) +{ + u8 pwr; + int i; + + /* feng: modify ulong to ushort for 2.6.21 porting */ + if (power != (unsigned short)-1) { + for(i = 0; (i < 16)&&!(power&1); i++) power >>= 1; + power = i; + } + DBG("set power to %d\n", power); + + + if (host->power == power) + return; + + if (power == (unsigned short)-1) { + writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + goto out; + } + + /* + * Spec says that we should clear the power reg before setting + * a new value. Some controllers don't seem to like this though. + */ + if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) + writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); + + pwr = SDHCI_POWER_ON; + + /* + switch (power) { + case MSS_VDD_170: + case MSS_VDD_180: + case MSS_VDD_190: + pwr |= SDHCI_POWER_180; + break; + case MSS_VDD_290: + case MSS_VDD_300: + case MSS_VDD_310: + pwr |= SDHCI_POWER_300; + break; + case MSS_VDD_320: + case MSS_VDD_330: + case MSS_VDD_340: + pwr |= SDHCI_POWER_330; + break; + default: + // mask by feng, temply masked it for debug + //BUG(); + } + */ + + /* added for temp use */ + pwr |= SDHCI_POWER_330; + + writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL); + +out: + host->power = power; + +} + +/*****************************************************************************\ + * * + * MMC callbacks * + * * +\*****************************************************************************/ + +static void sdhci_request(struct mss_host *mmc, struct mss_ll_request *mrq) +{ + struct sdhci_host *host; + unsigned long flags; + + host = mss_to_host(mmc); + if (mmc->active_card != NULL) + host->card = mmc->active_card; + + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); + + sdhci_activate_led(host); + + host->mrq = mrq; + + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + tasklet_schedule(&host->finish_tasklet); + } else + sdhci_send_command(host, mrq->cmd); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void sdhci_set_ios(struct mss_host *mmc, struct mss_ios *ios) +{ + struct sdhci_host *host; + unsigned long flags; + u8 ctrl; + u32 intmask; + host = mss_to_host(mmc); + + DBG("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", + ios->clock, ios->bus_mode, ios->power_mode, + ios->chip_select, ios->vdd, ios->bus_width); + + spin_lock_irqsave(&host->lock, flags); + + /* + * Reset the chip on each power off. + * Should clear out any weird states. + */ + if (ios->power_mode == MSS_POWER_OFF) { + writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_init(host); + } + + sdhci_set_clock(host, ios->clock); + + if (ios->power_mode == MSS_POWER_OFF) + sdhci_set_power(host, -1); + else + sdhci_set_power(host, ios->vdd); + + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + if (ios->bus_width == MSS_BUSWIDTH_4BIT) + ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; + + /* temply masked by feng + if (ios->timing == MMC_TIMING_SD_HS) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + */ + + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + mmiowb(); + + + if (ios->sdio_int == MSS_SDIO_INT_EN) { + intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + intmask |= SDHCI_INT_CARD_INT; + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); + + intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); + intmask |= SDHCI_INT_CARD_INT; + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + } else { + intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + intmask &= ~(SDHCI_INT_CARD_INT); + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); + + intmask = readl(host->ioaddr + SDHCI_INT_ENABLE); + intmask &= ~(SDHCI_INT_CARD_INT); + writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); + } + + + memcpy(&host->mmc->ios, ios, sizeof(struct mss_ios)); + spin_unlock_irqrestore(&host->lock, flags); +} + +/* +static int sdhci_slot_is_wp(struct mss_slot *slot) +{ + struct sdhci_host *host; + int present; + + host = slot_to_host(slot); + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + return !(present & SDHCI_WRITE_PROTECT); +} + +static int sdhci_slot_is_empty(struct mss_slot *slot) +{ + struct sdhci_host *host; + int present; + + host = slot_to_host(slot); + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + return !(present & SDHCI_CARD_PRESENT); +} + +static int sdhci_mss_slot_is_wp(struct mss_slot *slot) +{ + struct sdhci_host *host; + int result; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + result = sdhci_slot_is_wp(slot); + spin_unlock_irqrestore(&host->lock, flags); + return result; +} + +static int sdhci_mss_slot_is_empty(struct mss_slot *slot) +{ + struct sdhci_host *host; + int result; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + result = sdhci_slot_is_empty(slot); + spin_unlock_irqrestore(&host->lock, flags); + return result; +} +*/ + +static u32 sdhci_get_cur_state(struct mss_slot *slot) +{ + struct sdhci_host *host; + u32 state; + unsigned long flags; + + host = slot_to_host(slot); + spin_lock_irqsave(&host->lock, flags); + state = readl(host->ioaddr + SDHCI_PRESENT_STATE); + spin_unlock_irqrestore(&host->lock, flags); + return state; +} + +static int sdhci_mss_slot_is_wp(struct mss_slot *slot) +{ + return !( sdhci_get_cur_state(slot) & SDHCI_WRITE_PROTECT); +} + +static int sdhci_mss_slot_is_empty(struct mss_slot *slot) +{ + return !( sdhci_get_cur_state(slot) & SDHCI_CARD_PRESENT); +} + + +static struct mss_host_ops sdhci_ops = { + .request = sdhci_request, + .set_ios = sdhci_set_ios, + .is_slot_empty = sdhci_mss_slot_is_empty, + .is_slot_wp = sdhci_mss_slot_is_wp, +}; + +/*****************************************************************************\ + * * + * Tasklets * + * * +\*****************************************************************************/ + +static void sdhci_tasklet_card(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host*)param; + + spin_lock_irqsave(&host->lock, flags); + + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + if (host->mrq) { + printk(KERN_ERR "mmchost: Card removed during transfer!\n"); + printk(KERN_ERR "mmchost: Resetting controller.\n"); + + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + + host->mrq->cmd->error = MSS_ERROR_CRC; + tasklet_schedule(&host->finish_tasklet); + } + } + + spin_unlock_irqrestore(&host->lock, flags); + + + mss_detect_change(host->mmc, msecs_to_jiffies(500), 0); + //mmc_detect_change(host->mmc, msecs_to_jiffies(500)); + +} + +static void sdhci_tasklet_finish(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + struct mss_ll_request *mrq; + host = (struct sdhci_host*)param; + + spin_lock_irqsave(&host->lock, flags); + + del_timer(&host->timer); + + mrq = host->mrq; + + DBG("Ending request, cmd (%x)\n", mrq->cmd->opcode); + + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + + if (mrq->cmd->error != MSS_ERROR_NONE) { + //if ((mrq->cmd->error != MSS_ERROR_NONE) || + // (mrq->data && ((mrq->data->error != MSS_ERROR_NONE) || + // (mrq->data->stop && (mrq->data->stop->error != MSS_ERROR_NONE))))) { + + /* Some controllers need this kick or reset won't work here */ + if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { + unsigned int clock; + + /* This is to force an update */ + clock = host->clock; + host->clock = 0; + sdhci_set_clock(host, clock); + } + + /* Spec says we should do both at the same time, but Ricoh + controllers do not like that. */ + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + } + + +// printk(KERN_EMERG "%%%%%%%%%%%%%host->cmd = NULL; host->data = NULL %%%%%%%%%%%%%%%%%%%%\n"); + host->cmd = NULL; + host->data = NULL; + + sdhci_deactivate_led(host); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + + host->mrq->done(host->mrq); + host->mrq = NULL; +} + +static void sdhci_timeout_timer(unsigned long data) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host*)data; + + spin_lock_irqsave(&host->lock, flags); + + + + if (host->data) { + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + sdhci_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = MSS_ERROR_TIMEOUT; + else + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + + tasklet_schedule(&host->finish_tasklet); + } + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +/*****************************************************************************\ + * * + * Interrupt handling * + * * +\*****************************************************************************/ + +static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) +{ + BUG_ON(intmask == 0); + + if (!host->cmd) { + printk(KERN_ERR "mmchost: Got command interrupt even though no " + "command operation was in progress.\n"); + sdhci_dumpregs(host); + return; + } + + if (intmask & SDHCI_INT_RESPONSE) + sdhci_finish_command(host); + else { + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = MSS_ERROR_TIMEOUT; + else if (intmask & SDHCI_INT_CRC) + host->cmd->error = MSS_ERROR_CRC; + else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) + host->cmd->error = MSS_ERROR_CRC; + else + host->cmd->error = MSS_ERROR_CRC; + + tasklet_schedule(&host->finish_tasklet); + } +} + +static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) +{ + BUG_ON(intmask == 0); + + if (!host->data) { + /* + * A data end interrupt is sent together with the response + * for the stop command. + */ + if (intmask & SDHCI_INT_DATA_END) + return; + + printk(KERN_ERR "mmchost: Got data interrupt even though no " + "data operation was in progress.\n"); + sdhci_dumpregs(host); + + return; + } + + if (intmask & SDHCI_INT_DATA_TIMEOUT) + host->mrq->cmd->error = MSS_ERROR_TIMEOUT; + else if (intmask & SDHCI_INT_DATA_CRC) + host->mrq->cmd->error = MSS_ERROR_CRC; + else if (intmask & SDHCI_INT_DATA_END_BIT) + host->mrq->cmd->error = MSS_ERROR_CRC; + + if (host->mrq->cmd->error != MSS_ERROR_NONE) + sdhci_finish_data(host); + else { + if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) + sdhci_transfer_pio(host); + + if (intmask & SDHCI_INT_DATA_END) + sdhci_finish_data(host); + } +} + +/* static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs) */ +static irqreturn_t sdhci_irq(int irq, void *dev_id) +{ + irqreturn_t result; + struct sdhci_host* host = dev_id; + u32 intmask; + struct mss_driver *drv; + struct mss_card *card; + u32 imask; + + spin_lock(&host->lock); + + intmask = readl(host->ioaddr + SDHCI_INT_STATUS); + + if (!intmask || intmask == 0xffffffff) { + result = IRQ_NONE; + goto out; + } + + DBG("*** %s got interrupt: 0x%08x\n", host->slot_descr, intmask); + + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { + writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), + host->ioaddr + SDHCI_INT_STATUS); + tasklet_schedule(&host->card_tasklet); + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); + + if (intmask & SDHCI_INT_CMD_MASK) { + writel(intmask & SDHCI_INT_CMD_MASK, + host->ioaddr + SDHCI_INT_STATUS); + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + } + + if (intmask & SDHCI_INT_DATA_MASK) { + writel(intmask & SDHCI_INT_DATA_MASK, + host->ioaddr + SDHCI_INT_STATUS); + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); + } + + /* previous sdhci.c has no code for card interrupt handling */ + if (intmask & SDHCI_INT_CARD_INT) { + /* disable the card interrupt */ + imask = readl(host->ioaddr + SDHCI_INT_ENABLE); + imask &= ~(SDHCI_INT_CARD_INT); + writel(imask, host->ioaddr + SDHCI_INT_ENABLE); + + /* send the card interrupt to the SDIO app driver */ + card = host->card; + if (card) + drv = container_of(card->dev.driver, struct mss_driver, driver); + if (card && drv && (drv->sdio_int_handler != NULL)) + drv->sdio_int_handler(card); + } + + + intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); + + if (intmask & SDHCI_INT_BUS_POWER) { + printk(KERN_ERR "mmchost: Card is consuming too much power!\n"); + writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); + } + + intmask &= SDHCI_INT_BUS_POWER; + + if (intmask) { + printk(KERN_ERR "mmchost: Unexpected interrupt 0x%08x.\n", intmask); + sdhci_dumpregs(host); + + writel(intmask, host->ioaddr + SDHCI_INT_STATUS); + } + + result = IRQ_HANDLED; + + + mmiowb(); +out: + spin_unlock(&host->lock); + + return result; +} + +/*****************************************************************************\ + * * + * Suspend/resume * + * * +\*****************************************************************************/ + +#ifdef CONFIG_PM + +static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state) +{ + struct sdhci_chip *chip; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + DBG("Suspending...\n"); + + pci_save_state(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + + for (i = 0;i < chip->num_slots;i++) { + if (!chip->hosts[i]) + continue; + free_irq(chip->hosts[i]->irq, chip->hosts[i]); + } + + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int sdhci_resume (struct pci_dev *pdev) +{ + struct sdhci_chip *chip; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + DBG("Resuming...\n"); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + + for (i = 0;i < chip->num_slots;i++) { + if (!chip->hosts[i]) + continue; + if (chip->hosts[i]->flags & SDHCI_USE_DMA) + pci_set_master(pdev); + ret = request_irq(chip->hosts[i]->irq, sdhci_irq, + IRQF_SHARED, chip->hosts[i]->slot_descr, + chip->hosts[i]); + if (ret) + return ret; + sdhci_init(chip->hosts[i]); + mmiowb(); + } + + return 0; +} + +#else /* CONFIG_PM */ + +#define sdhci_suspend NULL +#define sdhci_resume NULL + +#endif /* CONFIG_PM */ + +/*****************************************************************************\ + * * + * Device probing/removal * + * * +\*****************************************************************************/ + +static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) +{ + int ret; + unsigned int version; + struct sdhci_chip *chip; + struct mss_host *mmc; + struct sdhci_host *host; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_sdhci = NULL; + char pbuf[50]; +#endif + u8 first_bar; + unsigned int caps; + + u32 tmpval; + + + chip = pci_get_drvdata(pdev); + BUG_ON(!chip); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) + return ret; + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + + if (first_bar > 5) { + printk(KERN_ERR DRIVER_NAME ": Invalid first BAR. Aborting.\n"); + return -ENODEV; + } + + if (!(pci_resource_flags(pdev, first_bar + slot) & IORESOURCE_MEM)) { + printk(KERN_ERR DRIVER_NAME ": BAR is not iomem. Aborting.\n"); + return -ENODEV; + } + + tmpval = pci_resource_len(pdev, first_bar + slot); + + if (pci_resource_len(pdev, first_bar + slot) != 0x100) { + printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. " + "You may experience problems.\n"); + } + + if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { + printk(KERN_ERR DRIVER_NAME ": Vendor specific interface. Aborting.\n"); + return -ENODEV; + } + + if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) { + printk(KERN_ERR DRIVER_NAME ": Unknown interface. Aborting.\n"); + return -ENODEV; + } + + //DBG("starting mss alloc process\n"); + + mmc = mss_alloc_host(1, 0, sizeof(struct sdhci_host)); + if (!mmc) + return -ENOMEM; + + host = mss_to_host(mmc); + host->mmc = mmc; + + host->chip = chip; + chip->hosts[slot] = host; + + mmc->slots->private = host; + host->card = NULL; + host->bar = first_bar + slot; + + host->addr = pci_resource_start(pdev, host->bar); + host->irq = pdev->irq; + + + snprintf(host->slot_descr, 20, "sdhci:slot%d", slot); + ret = pci_request_region(pdev, host->bar, host->slot_descr); + if (ret) + goto free; + + host->ioaddr = ioremap_nocache(host->addr, + pci_resource_len(pdev, host->bar)); + if (!host->ioaddr) { + ret = -ENOMEM; + goto release; + } + + sdhci_reset(host, SDHCI_RESET_ALL); + + version = readw(host->ioaddr + SDHCI_HOST_VERSION); + version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; + if (version != 0) { + printk(KERN_ERR "%s: Unknown controller version (%d). " + "You may experience problems.\n", host->slot_descr, + version); + } + + caps = readl(host->ioaddr + SDHCI_CAPABILITIES); + + /*on R5C832 controller we just assume the DMA is supported. It is a work round to fix the silicon bug*/ + // caps &= ~SDHCI_CAN_DO_DMA; + + if (debug_nodma) + DBG("DMA forced off\n"); + else if (debug_forcedma) { + DBG("DMA forced on\n"); + host->flags |= SDHCI_USE_DMA; + } else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA) + host->flags |= SDHCI_USE_DMA; + /* mask the check point for some DMA capable SDIO controller + reporting wrong information to PCI, and "caps" should be + enough for judging DMA capability */ + /* else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) + DBG("Controller doesn't have DMA interface\n"); */ + else if (!(caps & SDHCI_CAN_DO_DMA)) + DBG("Controller doesn't have DMA capability\n"); + else + host->flags |= SDHCI_USE_DMA; + + if (host->flags & SDHCI_USE_DMA) { + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + printk(KERN_WARNING "%s: No suitable DMA available. " + "Falling back to PIO.\n", host->slot_descr); + host->flags &= ~SDHCI_USE_DMA; + } + } + + if (host->flags & SDHCI_USE_DMA) + pci_set_master(pdev); + else /* XXX: Hack to get MMC layer to avoid highmem */ + pdev->dma_mask = 0; + + host->max_clk = + (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; + if (host->max_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify base clock " + "frequency.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + host->max_clk *= 1000000; + + host->timeout_clk = + (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; + if (host->timeout_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " + "frequency.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + if (caps & SDHCI_TIMEOUT_CLK_UNIT) + host->timeout_clk *= 1000; + + host->max_block = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; + if (host->max_block >= 3) { + printk(KERN_ERR "%s: Invalid maximum block size.\n", + host->slot_descr); + ret = -ENODEV; + goto unmap; + } + host->max_block = 512 << host->max_block; + + + /* Set host parameters. */ + mmc->ops = &sdhci_ops; + mmc->f_min = host->max_clk / 256; + mmc->f_max = host->max_clk; + mmc->dev = &pdev->dev; + mmc->vdd = 0; + + if (caps & SDHCI_CAN_VDD_330) { + mmc->vdd |= MSS_VDD_32_33|MSS_VDD_33_34; + } else if (caps & SDHCI_CAN_VDD_300) { + mmc->vdd |= MSS_VDD_29_30|MSS_VDD_30_31; + } else if (caps & SDHCI_CAN_VDD_180) { + mmc->vdd |= MSS_VDD_170_195; + } + mmc->ios.vdd = mmc->vdd; + + if (mmc->vdd == 0) { + printk(KERN_ERR "%s: Hardware doesn't report any " + "support voltages.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + mmc->bus_width = MSS_BUSWIDTH_4BIT; + + spin_lock_init(&host->lock); + + /* + * Maximum number of segments. Hardware cannot do scatter lists. + */ + if (host->flags & SDHCI_USE_DMA) + mmc->max_hw_segs = 1; + else + mmc->max_hw_segs = 16; + mmc->max_phys_segs = 16; + + /* + * Maximum number of sectors in one transfer. Limited by DMA boundary + * size (512KiB), which means (512 KiB/512=) 1024 entries. + */ + mmc->max_sectors = 1024; + + /* + * Maximum segment size. Could be one segment with the maximum number + * of sectors. + */ + mmc->max_seg_size = mmc->max_sectors * 512; + + /* + * Init tasklets. + */ + tasklet_init(&host->card_tasklet, + sdhci_tasklet_card, (unsigned long)host); + tasklet_init(&host->finish_tasklet, + sdhci_tasklet_finish, (unsigned long)host); + + setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); + + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, + host->slot_descr, host); + if (ret) + goto untasklet; + + sdhci_init(host); + mmiowb(); + + register_mss_host(mmc); + + printk(KERN_INFO "mmchost: SDHCI at 0x%08lx irq %d %s\n", + host->addr, host->irq, + (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); + + + mss_detect_change(host->mmc, msecs_to_jiffies(500), 0); + + +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + sprintf(pbuf, "%s.%d", pci_name(pdev), slot); + if ((proc_sdhci = create_proc_entry(pbuf, S_IRUSR | S_IRGRP | S_IROTH, dir_sdhci)) != NULL) + { + proc_sdhci->read_proc = sdhci_read_proc; + proc_sdhci->data = host; + } + } +#endif + return 0; + +untasklet: + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); +unmap: + iounmap(host->ioaddr); +release: + pci_release_region(pdev, host->bar); +free: + mss_free_host(mmc); + return ret; +} + +static void sdhci_remove_slot(struct pci_dev *pdev, int slot) +{ + struct sdhci_chip *chip; + struct mss_host *mmc; + struct sdhci_host *host; + struct mss_slot *mslot; + +#ifdef CONFIG_PROC_FS + char pbuf[50]; +#endif + + chip = pci_get_drvdata(pdev); + host = chip->hosts[slot]; + mmc = host->mmc; + + mslot = &mmc->slots[slot]; + if (mslot->card) + mss_force_card_remove(mslot->card); + + unregister_mss_host(mmc); + chip->hosts[slot] = NULL; + + sdhci_reset(host, SDHCI_RESET_ALL); + + free_irq(host->irq, host); + + del_timer_sync(&host->timer); + + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); + + iounmap(host->ioaddr); + + pci_release_region(pdev, host->bar); + +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + sprintf(pbuf, "%s.%d", pci_name(pdev), slot); + remove_proc_entry(pbuf, dir_sdhci); + } +#endif + mss_free_host(mmc); +} + +static int __devinit sdhci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret, i; + u8 slots, rev; + struct sdhci_chip *chip; + + + BUG_ON(pdev == NULL); + BUG_ON(ent == NULL); + + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); + + printk(KERN_INFO DRIVER_NAME + ": SDHCI controller found at %s [%04x:%04x] (rev %x)\n", + pci_name(pdev), (int)pdev->vendor, (int)pdev->device, + (int)rev); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) + return ret; + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + if (slots == 0) + return -ENODEV; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + chip = kzalloc(sizeof(struct sdhci_chip) + + sizeof(struct sdhci_host*) * slots, GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + goto err; + } + + chip->pdev = pdev; + chip->quirks = ent->driver_data; + + if (debug_quirks) + chip->quirks = debug_quirks; + + chip->num_slots = slots; + pci_set_drvdata(pdev, chip); + + for (i = 0;i < slots;i++) { + ret = sdhci_probe_slot(pdev, i); + if (ret) { + for (i--;i >= 0;i--) + sdhci_remove_slot(pdev, i); + goto free; + } + } + + return 0; + +free: + pci_set_drvdata(pdev, NULL); + kfree(chip); +err: + pci_disable_device(pdev); + return ret; +} + +static void __devexit sdhci_remove(struct pci_dev *pdev) +{ + int i; + struct sdhci_chip *chip; + + chip = pci_get_drvdata(pdev); + + if (chip) { + for (i = 0;i < chip->num_slots;i++) + sdhci_remove_slot(pdev, i); + + pci_set_drvdata(pdev, NULL); + + kfree(chip); + } + + pci_disable_device(pdev); +} + +static struct pci_driver sdhci_driver = { + .name = DRIVER_NAME, + .id_table = pci_ids, + .probe = sdhci_probe, + .remove = __devexit_p(sdhci_remove), + .suspend = sdhci_suspend, + .resume = sdhci_resume, +}; + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdhci_drv_init(void) +{ + printk(KERN_INFO DRIVER_NAME + ": Secure Digital Host Controller Interface driver\n"); + printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); + + + +#ifdef CONFIG_PROC_FS + if ((dir_sdhci = proc_mkdir("sdhci", NULL)) == NULL) + printk(KERN_WARNING "SDHCI failed to create proc interface\n"); +#endif + return pci_register_driver(&sdhci_driver); +} + +static void __exit sdhci_drv_exit(void) +{ + pci_unregister_driver(&sdhci_driver); +#ifdef CONFIG_PROC_FS + if (dir_sdhci) { + remove_proc_entry("sdhci", NULL); + dir_sdhci = NULL; + } +#endif +} + +module_init(sdhci_drv_init); +module_exit(sdhci_drv_exit); + +module_param(debug_nodma, uint, 0444); +module_param(debug_forcedma, uint, 0444); +module_param(debug_quirks, uint, 0444); + +MODULE_AUTHOR("Pierre Ossman "); +MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); +MODULE_LICENSE("GPL"); + +MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)"); +MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)"); +MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/mss_sdhci.h +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/mss_sdhci.h @@ -0,0 +1,248 @@ +/* + * mss_sdhci.h - SD Host Controller interface driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * derived from linux/drivers/mmc/sdhci.h + * Copyright (c) 2005 Pierre Ossman + */ + + +/* + * PCI registers + */ +#define MSS_VDD_150 0 +#define MSS_VDD_155 1 +#define MSS_VDD_160 2 +#define MSS_VDD_165 3 +#define MSS_VDD_170 4 +#define MSS_VDD_180 5 +#define MSS_VDD_190 6 +#define MSS_VDD_200 7 +#define MSS_VDD_210 8 +#define MSS_VDD_220 9 +#define MSS_VDD_230 10 +#define MSS_VDD_240 11 +#define MSS_VDD_250 12 +#define MSS_VDD_260 13 +#define MSS_VDD_270 14 +#define MSS_VDD_280 15 +#define MSS_VDD_290 16 +#define MSS_VDD_300 17 +#define MSS_VDD_310 18 +#define MSS_VDD_320 19 +#define MSS_VDD_330 20 +#define MSS_VDD_340 21 +#define MSS_VDD_350 22 +#define MSS_VDD_360 23 + +#define PCI_SDHCI_IFPIO 0x00 +#define PCI_SDHCI_IFDMA 0x01 +#define PCI_SDHCI_IFVENDOR 0x02 + +#define PCI_SLOT_INFO 0x40 /* 8 bits */ +#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) +#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 + +/* + * Controller registers + */ +#define SDHCI_DMA_ADDRESS 0x00 +#define SDHCI_BLOCK_SIZE 0x04 +#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) + +#define SDHCI_BLOCK_COUNT 0x06 +#define SDHCI_ARGUMENT 0x08 + +#define SDHCI_TRANSFER_MODE 0x0C +#define SDHCI_TRNS_DMA 0x01 +#define SDHCI_TRNS_BLK_CNT_EN 0x02 +#define SDHCI_TRNS_ACMD12 0x04 +#define SDHCI_TRNS_READ 0x10 +#define SDHCI_TRNS_MULTI 0x20 + +#define SDHCI_COMMAND 0x0E +#define SDHCI_CMD_RESP_MASK 0x03 +#define SDHCI_CMD_CRC 0x08 +#define SDHCI_CMD_INDEX 0x10 +#define SDHCI_CMD_DATA 0x20 + +#define SDHCI_CMD_RESP_NONE 0x00 +#define SDHCI_CMD_RESP_LONG 0x01 +#define SDHCI_CMD_RESP_SHORT 0x02 +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 + +#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) + +#define SDHCI_RESPONSE 0x10 +#define SDHCI_BUFFER 0x20 +#define SDHCI_PRESENT_STATE 0x24 + +#define SDHCI_CMD_INHIBIT 0x00000001 +#define SDHCI_DATA_INHIBIT 0x00000002 +#define SDHCI_DOING_WRITE 0x00000100 +#define SDHCI_DOING_READ 0x00000200 +#define SDHCI_SPACE_AVAILABLE 0x00000400 +#define SDHCI_DATA_AVAILABLE 0x00000800 +#define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_WRITE_PROTECT 0x00080000 + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_LED 0x01 +#define SDHCI_CTRL_4BITBUS 0x02 +#define SDHCI_CTRL_HISPD 0x04 + +#define SDHCI_POWER_CONTROL 0x29 +#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_180 0x0A +#define SDHCI_POWER_300 0x0C +#define SDHCI_POWER_330 0x0E + +#define SDHCI_BLOCK_GAP_CONTROL 0x2A + +#define SDHCI_WALK_UP_CONTROL 0x2B + +#define SDHCI_CLOCK_CONTROL 0x2C +#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_CLOCK_CARD_EN 0x0004 +#define SDHCI_CLOCK_INT_STABLE 0x0002 +#define SDHCI_CLOCK_INT_EN 0x0001 + +#define SDHCI_TIMEOUT_CONTROL 0x2E + +#define SDHCI_SOFTWARE_RESET 0x2F +#define SDHCI_RESET_ALL 0x01 +#define SDHCI_RESET_CMD 0x02 +#define SDHCI_RESET_DATA 0x04 + +#define SDHCI_INT_STATUS 0x30 +#define SDHCI_INT_ENABLE 0x34 +#define SDHCI_SIGNAL_ENABLE 0x38 +#define SDHCI_INT_RESPONSE 0x00000001 +#define SDHCI_INT_DATA_END 0x00000002 +#define SDHCI_INT_BLK_GAP 0x00000004 +#define SDHCI_INT_DMA_END 0x00000008 +#define SDHCI_INT_SPACE_AVAIL 0x00000010 +#define SDHCI_INT_DATA_AVAIL 0x00000020 +#define SDHCI_INT_CARD_INSERT 0x00000040 +#define SDHCI_INT_CARD_REMOVE 0x00000080 +#define SDHCI_INT_CARD_INT 0x00000100 +#define SDHCI_INT_ERROR 0x00008000 +#define SDHCI_INT_TIMEOUT 0x00010000 +#define SDHCI_INT_CRC 0x00020000 +#define SDHCI_INT_END_BIT 0x00040000 +#define SDHCI_INT_INDEX 0x00080000 +#define SDHCI_INT_DATA_TIMEOUT 0x00100000 +#define SDHCI_INT_DATA_CRC 0x00200000 +#define SDHCI_INT_DATA_END_BIT 0x00400000 +#define SDHCI_INT_BUS_POWER 0x00800000 +#define SDHCI_INT_ACMD12ERR 0x01000000 + +#define SDHCI_INT_NORMAL_MASK 0x00007FFF +#define SDHCI_INT_ERROR_MASK 0xFFFF8000 + +#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ + SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) +#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ + SDHCI_INT_DATA_END_BIT) + +#define SDHCI_ACMD12_ERR 0x3C + +/* 3E-3F reserved */ + +#define SDHCI_CAPABILITIES 0x40 +#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F +#define SDHCI_TIMEOUT_CLK_SHIFT 0 +#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 +#define SDHCI_CLOCK_BASE_MASK 0x00003F00 +#define SDHCI_CLOCK_BASE_SHIFT 8 +#define SDHCI_MAX_BLOCK_MASK 0x00030000 +#define SDHCI_MAX_BLOCK_SHIFT 16 +#define SDHCI_CAN_DO_HISPD 0x00200000 +#define SDHCI_CAN_DO_DMA 0x00400000 +#define SDHCI_CAN_VDD_330 0x01000000 +#define SDHCI_CAN_VDD_300 0x02000000 +#define SDHCI_CAN_VDD_180 0x04000000 + +/* 44-47 reserved for more caps */ + +#define SDHCI_MAX_CURRENT 0x48 + +/* 4C-4F reserved for more max current */ +/* 50-FB reserved */ + +#define SDHCI_SLOT_INT_STATUS 0xFC + +#define SDHCI_HOST_VERSION 0xFE +#define SDHCI_VENDOR_VER_MASK 0xFF00 +#define SDHCI_VENDOR_VER_SHIFT 8 +#define SDHCI_SPEC_VER_MASK 0x00FF +#define SDHCI_SPEC_VER_SHIFT 0 + +#define SDHCI_USE_DMA (1<<0) + +struct sdhci_chip; + +struct sdhci_host { + struct sdhci_chip *chip; + struct mss_host *mmc; /* MMC structure */ + + spinlock_t lock; /* Mutex */ + int flags; /* Host attributes */ + + + unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int max_block; /* Max block size (bytes) */ + + unsigned int clock; /* Current clock (MHz) */ + unsigned short power; /* Current voltage */ + + struct mss_ll_request *mrq; /* Current request */ + struct mss_cmd *cmd; /* Current command */ + struct mss_data *data; /* Current data request */ + struct mss_card *card; + + struct scatterlist *cur_sg; /* We're working on this */ + char *mapped_sg; /* This is where it's mapped */ + int num_sg; /* Entries left */ + int offset; /* Offset into current sg */ + int remain; /* Bytes left in current */ + int size; /* Remaining bytes in transfer */ + + char slot_descr[20]; /* Name for reservations */ + int irq; /* Device IRQ */ + int bar; /* PCI BAR index */ + unsigned long addr; /* Bus address */ + void __iomem * ioaddr; /* Mapped address */ + + struct tasklet_struct card_tasklet; /* Tasklet structures */ + struct tasklet_struct finish_tasklet; + + struct timer_list timer; /* Timer for timeouts */ +}; + +struct sdhci_chip { + struct pci_dev *pdev; + unsigned long quirks; + int num_slots; /* Slots on controller */ + struct sdhci_host *hosts[0]; /* Pointers to hosts */ +}; --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/mmc_protocol.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/mmc_protocol.c @@ -0,0 +1,1049 @@ +/* + * mmc_protocol.c - MMC protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* internal functions */ + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 mmc_tran_speed(u8 ts) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + return clock; +} + +static int mmc_unpack_r1(struct mss_cmd *cmd, struct mmc_response_r1 *r1, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + mmc_card->errno = MMC_ERROR_OUT_OF_RANGE; + if (r1->status & R1_ADDRESS_ERROR) + mmc_card->errno = MMC_ERROR_ADDRESS; + if (r1->status & R1_BLOCK_LEN_ERROR) + mmc_card->errno = MMC_ERROR_BLOCK_LEN; + if (r1->status & R1_ERASE_SEQ_ERROR) + mmc_card->errno = MMC_ERROR_ERASE_SEQ; + if (r1->status & R1_ERASE_PARAM) + mmc_card->errno = MMC_ERROR_ERASE_PARAM; + if (r1->status & R1_WP_VIOLATION) + mmc_card->errno = MMC_ERROR_WP_VIOLATION; + if (r1->status & R1_LOCK_UNLOCK_FAILED) + mmc_card->errno = MMC_ERROR_LOCK_UNLOCK_FAILED; + if (r1->status & R1_COM_CRC_ERROR) + mmc_card->errno = MMC_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + mmc_card->errno = MMC_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_CARD_ECC_FAILED) + mmc_card->errno = MMC_ERROR_CARD_ECC_FAILED; + if (r1->status & R1_CC_ERROR) + mmc_card->errno = MMC_ERROR_CC; + if (r1->status & R1_ERROR) + mmc_card->errno = MMC_ERROR_GENERAL; + if (r1->status & R1_UNDERRUN) + mmc_card->errno = MMC_ERROR_UNDERRUN; + if (r1->status & R1_OVERRUN) + mmc_card->errno = MMC_ERROR_OVERRUN; + if (r1->status & R1_CID_CSD_OVERWRITE) + mmc_card->errno = MMC_ERROR_CID_CSD_OVERWRITE; + } + + if (buf[0] != cmd->opcode) + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + /* This should be last - it's the least dangerous error */ + if (R1_CURRENT_STATE(r1->status) != mmc_card->state ) { + dbg5("state dismatch:r1->status:%x,state:%x\n",R1_CURRENT_STATE(r1->status),mmc_card->state); + mmc_card->errno = MMC_ERROR_STATE_MISMATCH; + } + dbg5("mmc card error %d", mmc_card->errno); + if (mmc_card->errno) + return MSS_ERROR_RESP_UNPACK; + return 0; +} + +static int mmc_unpack_r3(struct mss_cmd *cmd, struct mmc_response_r3 *r3, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + r3->cmd = unstuff_bits(buf, 40, 8, 6); + r3->ocr = unstuff_bits(buf, 8, 32, 6); + + if (r3->cmd != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0; +} + +/** + * Fast I/O, support for CEATA devices. + */ +static int mmc_unpack_r4( struct mss_cmd *cmd, struct mmc_response_r4 *r4, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + + r4->cmd = unstuff_bits(buf, 40, 8, 6); + r4->rca = unstuff_bits(buf, 24, 16, 6); + r4->status = unstuff_bits(buf, 23, 1, 6); + r4->reg_addr = unstuff_bits(buf, 16, 7, 6); + r4->read_reg_contents = unstuff_bits(buf, 8, 8, 6); + + if (r4->cmd != 0x27) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0 ; +} + +/** + * Interrupt request. not supported temporarily. + */ +static int mmc_unpack_r5(struct mss_cmd *cmd, struct mmc_response_r5 *r5, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + + r5->cmd = unstuff_bits(buf, 40, 8, 6); + r5->rca = unstuff_bits(buf, 24, 16, 6); + r5->irq_data = unstuff_bits(buf, 8, 16, 6); + + if (r5->cmd != 0x28) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + return 0 ; +} + +static int mmc_unpack_cid(struct mss_cmd *cmd, struct mmc_cid *cid, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + if (buf[0] != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + cid->mid = unstuff_bits(buf, 120, 8, 16); + cid->oid = unstuff_bits(buf, 104, 16, 16); + cid->pnm[0] = unstuff_bits(buf, 96, 8, 16); + cid->pnm[1] = unstuff_bits(buf, 88, 8, 16); + cid->pnm[2] = unstuff_bits(buf, 80, 8, 16); + cid->pnm[3] = unstuff_bits(buf, 72, 8, 16); + cid->pnm[4] = unstuff_bits(buf, 64, 8, 16); + cid->pnm[5] = unstuff_bits(buf, 56, 8, 16); + cid->pnm[6] = 0; + cid->prv = unstuff_bits(buf, 48, 8, 16); + cid->psn = unstuff_bits(buf, 16, 32, 16); + cid->mdt = unstuff_bits(buf, 8, 8, 16); + + return 0; +} + +static int mmc_unpack_csd(struct mss_cmd *cmd, struct mmc_csd *csd, struct mmc_card *mmc_card) +{ + u8 *buf = cmd->response; + + mmc_card->errno = MMC_ERROR_NONE; + if (buf[0] != 0x3f) { + mmc_card->errno = MMC_ERROR_HEADER_MISMATCH; + return MSS_ERROR_RESP_UNPACK; + } + buf = buf + 1; + + csd->csd_structure = unstuff_bits(buf, 126, 2, 16); + csd->spec_vers = unstuff_bits(buf, 122, 4, 16); + csd->taac = unstuff_bits(buf, 112, 8, 16); + csd->nsac = unstuff_bits(buf, 104, 8, 16); + csd->tran_speed = unstuff_bits(buf, 96, 8, 16); + csd->ccc = unstuff_bits(buf, 84, 12, 16);; + csd->read_bl_len = unstuff_bits(buf, 80, 4, 16); + csd->read_bl_partial = unstuff_bits(buf, 79, 1, 16); + csd->write_blk_misalign = unstuff_bits(buf, 78, 1, 16); + csd->read_blk_misalign = unstuff_bits(buf, 77, 1, 16); + csd->dsr_imp = unstuff_bits(buf, 76, 1, 16); + csd->c_size = unstuff_bits(buf, 62, 12, 16); + csd->vdd_r_curr_min = unstuff_bits(buf, 59, 3, 16); + csd->vdd_r_curr_max = unstuff_bits(buf, 56, 3, 16); + csd->vdd_w_curr_min = unstuff_bits(buf, 53, 3, 16); + csd->vdd_w_curr_max = unstuff_bits(buf, 50, 3, 16); + csd->c_size_mult = unstuff_bits(buf, 47, 3, 16); + switch (csd->csd_structure ) { + case CSD_STRUCT_1_0: + case CSD_STRUCT_1_1: + csd->erase.v22.sector_size = + unstuff_bits(buf, 42, 5, 16); + csd->erase.v22.erase_grp_size = + unstuff_bits(buf, 37, 5, 6); + break; + case CSD_STRUCT_1_2: + default: + csd->erase.v31.erase_grp_size = + unstuff_bits(buf, 42, 5, 16); + csd->erase.v31.erase_grp_mult = + unstuff_bits(buf, 37, 5, 16);; + break; + } + csd->wp_grp_size = unstuff_bits(buf, 32, 5, 16); + csd->wp_grp_enable = unstuff_bits(buf, 31, 1, 16); + csd->default_ecc = unstuff_bits(buf, 29, 2, 16); + csd->r2w_factor = unstuff_bits(buf, 26, 3, 16); + csd->write_bl_len = unstuff_bits(buf, 22, 4, 16); + csd->write_bl_partial = unstuff_bits(buf, 21, 1, 16); + csd->file_format_grp = unstuff_bits(buf, 16, 1, 16); + csd->copy = unstuff_bits(buf, 14, 1, 16); + csd->perm_write_protect = unstuff_bits(buf, 13, 1, 16); + csd->tmp_write_protect = unstuff_bits(buf, 12, 1, 16); + csd->file_format = unstuff_bits(buf, 10, 2, 16); + csd->ecc = unstuff_bits(buf, 8, 2, 16); + + printk(" csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x\n" + " ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d\n" + " read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d\n" + " vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d\n" + " wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d\n" + " write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d\n" + " perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d\n", + csd->csd_structure, csd->spec_vers, + csd->taac, csd->nsac, csd->tran_speed, + csd->ccc, csd->read_bl_len, + csd->read_bl_partial, csd->write_blk_misalign, + csd->read_blk_misalign, csd->dsr_imp, + csd->c_size, csd->vdd_r_curr_min, + csd->vdd_r_curr_max, csd->vdd_w_curr_min, + csd->vdd_w_curr_max, csd->c_size_mult, + csd->wp_grp_size, csd->wp_grp_enable, + csd->default_ecc, csd->r2w_factor, + csd->write_bl_len, csd->write_bl_partial, + csd->file_format_grp, csd->copy, + csd->perm_write_protect, csd->tmp_write_protect, + csd->file_format, csd->ecc); + switch ( csd->csd_structure ) { + case CSD_STRUCT_1_0: + case CSD_STRUCT_1_1: + printk(" V22 sector_size=%d erase_grp_size=%d\n", + csd->erase.v22.sector_size, + csd->erase.v22.erase_grp_size); + break; + case CSD_STRUCT_1_2: + default: + printk(" V31 erase_grp_size=%d erase_grp_mult=%d\n", + csd->erase.v31.erase_grp_size, + csd->erase.v31.erase_grp_mult); + break; + + } + + return MSS_ERROR_NONE; +} + +static int mmc_unpack_ext_csd(u8 *buf, struct mmc_ext_csd *ext_csd) +{ + ext_csd->s_cmd_set = buf[504]; + ext_csd->sec_count = ((u32)buf[212]) << 24 | ((u32)buf[213]) << 16 | ((u32)buf[214]) << 8 | ((u32)buf[215]) ; + ext_csd->min_perf_w_8_52 = buf[210]; + ext_csd->min_perf_r_8_52 = buf[209]; + ext_csd->min_perf_w_26_4_52 = buf[208]; + ext_csd->min_perf_r_26_4_52 = buf[207]; + ext_csd->min_perf_w_4_26 = buf[206]; + ext_csd->min_perf_r_4_26 = buf[205]; + ext_csd->pwr_cl_26_360 = buf[203]; + ext_csd->pwr_cl_52_360 = buf[202]; + ext_csd->pwr_cl_26_195 = buf[201]; + ext_csd->pwr_cl_52_195 = buf[200]; + ext_csd->card_type = buf[196]; + ext_csd->csd_structure = buf[194]; + ext_csd->ext_csd_rev = buf[192]; + ext_csd->cmd_set = buf[191]; + ext_csd->cmd_set_rev = buf[189]; + ext_csd->power_class = buf[187]; + ext_csd->hs_timing = buf[185]; + ext_csd->erased_mem_cont = buf[183]; + + return 0; +} + +/** + * The blocks requested by the kernel may or may not match what we can do. + * Unfortunately, filesystems play fast and loose with block sizes, so we're + * stuck with this . + */ +static void mmc_fix_request_block_len(struct mss_card *card, int action, struct mss_rw_arg *arg) +{ + u16 block_len = 0; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + + switch(action) { + case MSS_DATA_READ: + block_len = 1 << mmc_card->csd.read_bl_len; + break; + case MSS_DATA_WRITE: + block_len = 1 << mmc_card->csd.write_bl_len; + break; + default: + return; + } + if (host->high_capacity && mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR) + block_len = 512; + if (block_len < arg->block_len) { + int scale = arg->block_len / block_len; + arg->block_len = block_len; + arg->block *= scale; + arg->nob *= scale; + } +} + + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static u32 mmc_make_cmd6_arg(u8 access, u8 index, u8 value, u8 cmdset) +{ + u32 ret; + ret = (access << 24) | (index << 16) | (value << 8) | cmdset; + return ret; +} + +static int mmc_get_status(struct mss_card *card, u32 *status) +{ + struct mmc_response_r1 r1; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + int clock, ret, retries = 4; + + clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(card->slot->host, clock); + while (retries--) { + dbg5("rety"); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_STATUS, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg5("retry ret :%d", ret); + if (ret && !retries) + return ret; + else if (!ret) { + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + if (mmc_card->errno==MMC_ERROR_STATE_MISMATCH) { + mmc_card->state = + R1_CURRENT_STATE(r1.status); + mmc_card->errno = MMC_ERROR_NONE; + } + else + return ret; + } + else + break; + } + + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW || retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + } + + *status = r1.status; + + return MSS_ERROR_NONE; +} + +static int mmc_recognize_card(struct mss_card *card) +{ + struct mmc_response_r3 r3; + struct mmc_card *mmc_card = card->prot_card; + struct mss_ios ios; + struct mss_host *host = card->slot->host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + int ret; + u32 ocr = host->vdd; + + mmc_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + card->card_type = MSS_UNKNOWN_CARD; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + dbg2(card->slot, card->prot_driver, "Sending GO_IDLE cmd, ret:%d\n", ret); + if (ret) + return ret; + if (host->high_capacity) + ocr |= MMC_ACCESS_MODE_SECTOR; + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_OP_COND, ocr, + MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (!ret) { + if (r3.ocr & host->vdd) { + card->card_type = MSS_MMC_CARD; + } else { + printk(KERN_WARNING "uncompatible card\n"); + card->card_type = MSS_UNCOMPATIBLE_CARD; + } + return ret; + } + card->card_type = MSS_UNKNOWN_CARD; + + return MSS_ERROR_NONE; +} + +static int mmc_card_init(struct mss_card *card) +{ + struct mmc_response_r3 r3; + struct mmc_response_r1 r1; + struct mmc_cid cid; + struct mmc_card *mmc_card = card->prot_card; + struct mss_ios ios; + struct mss_host *host; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + struct mss_data *data = &mmc_card->data; + int ret; + u8 *g_buffer; + u32 ocr, arg, bus_width; + struct scatterlist sg; + + host = card->slot->host; + ocr = host->vdd; + + mmc_card->state = CARD_STATE_IDLE; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.bus_mode = MSS_BUSMODE_OPENDRAIN; + ios.bus_width = MSS_BUSWIDTH_1BIT; + ios.clock = host->f_min; + host->ops->set_ios(host, &ios); + + dbg2(card->slot, card->prot_driver, "Sending GO_IDLE cmd, ret:%d\n", ret); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_GO_IDLE_STATE, 0, + MSS_RESPONSE_NONE, MSS_CMD_INIT); + if (ret) + return ret; + + if (host->high_capacity) + ocr |= MMC_ACCESS_MODE_SECTOR; + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_OP_COND, ocr, + MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (ret) { + //printk(KERN_ERR "failed SEND_OP_COND error=%d (%s) \n", ret, mmc_result_to_string(ret)); + return ret; + } + + while (!(r3.ocr & MMC_CARD_BUSY)) { + //mdelay(20); + msleep(15); + dbg2(card->slot, card->prot_driver, "card is busy after SNED_OP_COND"); + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_SEND_OP_COND, ocr, MSS_RESPONSE_R3, 0); + dbg2(card->slot, card->prot_driver, "Sending SEND_OP_COND cmd, arg:0x%x\n, ret:%d", ocr, ret); + if (ret) + return ret; + ret = mmc_unpack_r3(cmd, &r3, mmc_card); + dbg2(card->slot, card->prot_driver, "unapck ret %d, SEND_OP_COND ocr:0x%x", ret, r3.ocr); + if (ret) { + //printk(KERN_ERR ": failed SEND_OP_COND error=%d (%s) \n", retval, mmc_result_to_string(retval) ); + return ret; + } + } + + mmc_card->vdd = r3.ocr & MMC_VDD_MASK; + mmc_card->access_mode = r3.ocr & MMC_ACCESS_MODE_MASK; + mmc_card->state = CARD_STATE_READY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_ALL_SEND_CID, 0, + MSS_RESPONSE_R2_CID, 0); + dbg2(card->slot, card->prot_driver, "Sending MMC_ALL_SEND_CID cmd, arg:0x%x\n, ret:%d", 0, ret); + if (ret) + return ret; + + memset(&cid, 0x0, sizeof(struct mmc_cid)); + ret = mmc_unpack_cid(cmd, &cid, mmc_card); + if (ret) + return ret; + + /* Not first init */ + if (mmc_card->cid.mid != 0) { + /* Card is changed */ + if (mmc_card->cid.mid != cid.mid || mmc_card->cid.oid != cid.oid + || mmc_card->cid.prv != cid.prv + || mmc_card->cid.psn != cid.psn + || mmc_card->cid.mdt != cid.mdt + || memcmp(mmc_card->cid.pnm, cid.pnm, 6)) + return MSS_ERROR_MISMATCH_CARD; + } + else + memcpy(&mmc_card->cid, &cid, sizeof(struct mmc_cid)); + + mmc_card->state = CARD_STATE_IDENT; + + mss_set_busmode(host, MSS_BUSMODE_PUSHPULL); + + mmc_card->rca = MMC_SLOT_RCA(card->slot); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SET_RELATIVE_ADDR, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + dbg2(card->slot, card->prot_driver, "Sending SET_REL_ADDR cmd, arg:0x%x\n, ret:%d", mmc_card->rca << 16, ret); + if (ret) + return ret; + + //mss_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, (dev->slot->rca) << 16, RESPONSE_R1, buffer); + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + //printk(KERN_INFO "MMC: unable to SET_RELATIVE_ADDR error=%d (%s)\n", retval, mmc_result_to_string(retval) ); + return ret; + } + mmc_card->state = CARD_STATE_STBY; + + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SEND_CSD, + mmc_card->rca << 16, MSS_RESPONSE_R2_CSD, 0); + dbg2(card->slot, card->prot_driver, "Sending MMC_SEND_CSD cmd, arg:0x%x\n, ret:%d", mmc_card->rca << 16, ret); + if (ret) + return ret; + ret = mmc_unpack_csd(cmd, &mmc_card->csd, mmc_card); + if (ret) { + //printk(KERN_INFO "MMC: unable to SEND_CSD error=%d (%s)\n", retval, mmc_result_to_string(retval) ); + return ret; + } + + /* + * if it is MMC4.x-compatible card and how many bits are working. + */ + if (mmc_card->csd.spec_vers != CSD_SPEC_VERS_4 + || host->mmc_spec != MSS_MMC_SPEC_40_42) + goto exit; + + g_buffer = mmc_card->buf;//kmalloc(512, GFP_KERNEL); + /*if (!g_buffer) + return -ENOMEM; */ + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, + mmc_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->state = CARD_STATE_TRAN; + + /* + * set 1-bus mode in init. arg:access=0b11, arg:index=0xb7, arg:value=0 + * or CMD8 will not be responded with 1-bit/controller and 4-bit/card + * dev->bus_mode should be MSS_1_BIT before next command + * buffer = NULL; + */ + arg = mmc_make_cmd6_arg(0x3, 0xb7, 0, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + card->bus_width = MSS_BUSWIDTH_1BIT; + mss_set_buswidth(host, MSS_BUSWIDTH_1BIT); + + sg.page = virt_to_page(g_buffer); + sg.offset = offset_in_page(g_buffer); + sg.length = 512; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_SEND_EXT_CSD, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_ext_csd(g_buffer, &mmc_card->ext_csd); + if (ret) + return ret; + + /* + * use CMD19/CMD14 (BUSTEST_W/BUSTEST_R) to test supported bus mode. + */ + memset(g_buffer, 0xFF, 512); + bus_width = host->bus_width; + if (bus_width == MSS_BUSWIDTH_1BIT) + goto exit; + else if (bus_width == MSS_BUSWIDTH_4BIT) { + card->bus_width = MSS_BUSWIDTH_4BIT; + g_buffer[0] = 0xa5; /* 0b10100101 */ + g_buffer[1] = 0xFF; /* 0b11111111 */ + } + else if (bus_width == MSS_BUSWIDTH_8BIT) { + card->bus_width = MSS_BUSWIDTH_8BIT; + g_buffer[0] = 0xaa; /* 0b10101010 */ + g_buffer[1] = 0x55; /* 0b01010101 */ + } + else + goto exit; + + mss_set_buswidth(host, bus_width); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_BUSTEST_W, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_WRITE, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + mmc_card->state = CARD_STATE_BTST; + memset(g_buffer, 0xFF, 512); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + MSS_INIT_CMD(cmd, MMC_BUSTEST_R, 0, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, 1, 512, MSS_DATA_READ, 1, &sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + if ((g_buffer[0] == 0x55/*0b01010101*/) && + (g_buffer[1] == 0xaa/*0b10101010*/)) { + mmc_card->bus_width = MSS_BUSWIDTH_8BIT; + } + else if (g_buffer[0] == 0x5a /*0b01011010*/) { + mmc_card->bus_width = MSS_BUSWIDTH_4BIT; + } + else { + mmc_card->bus_width = MSS_BUSWIDTH_1BIT; + } + + mmc_card->state = CARD_STATE_TRAN; + + arg = mmc_make_cmd6_arg(0x3, 0xb7, mmc_card->bus_width, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + + card->bus_width = mmc_card->bus_width; + /** + * use CMD6 to set high speed mode. arg:access=0b11, arg:index=0xb9, + * arg:value=1 according to card/controller high speed timing + * high speed mode for MMC-4.x compatible card. + */ + if (host->high_speed == MSS_HIGH_SPEED) { + mmc_make_cmd6_arg(0x3, 0xb9, 1, 0); + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SWITCH, arg, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.high_speed = MSS_HIGH_SPEED; + ios.clock = MMC_CARD_CLOCK_FAST; + host->ops->set_ios(host, &ios); + if (host->ios.high_speed != MSS_HIGH_SPEED) { + u32 clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(host, clock); + } + } + else { + /* change to the highest speed in normal mode */ + u32 clock = mmc_tran_speed(mmc_card->csd.tran_speed); + mss_set_clock(host, clock); + } + + /** + * use CMD6 to set power class. arg:access=0b11, arg:index=0xbb, + * arg:value=card power class code according to card/controller supported + * power class. We read value from PWL_CL_ff_vvv and set it to POWER_CLASS + * according to supported voltage and clock rate. + */ + + /* Deselect the card */ + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, 0, + MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->state = CARD_STATE_STBY; + +exit: + return MSS_ERROR_NONE; +} + +static int mmc_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host; + struct mss_ios ios; + struct mmc_response_r1 r1; + struct mss_ll_request *llreq = &mmc_card->llreq; + struct mss_cmd *cmd = &mmc_card->cmd; + struct mss_data *data = &mmc_card->data; + int ret, retries = 4, clock; + u32 status = 0; + int access_mode_sector = 0; + u32 cmdarg, blklen, opcode, flags; + + host = card->slot->host; + + ret = mmc_get_status(card, &status); + if (ret) + return ret; + + if (status & R1_CARD_IS_LOCKED) + return MSS_ERROR_LOCKED; + + if (action == MSS_WRITE_MEM && host->ops->is_slot_wp && + host->ops->is_slot_wp(card->slot)) + return MSS_ERROR_WP; + + if (mmc_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, MMC_SELECT_CARD, + mmc_card->rca << 16, MSS_RESPONSE_R1, 0); + if (ret) + return ret; + dbg5("select card cmd return ret:%d\n", ret); + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + } + mmc_card->state = CARD_STATE_TRAN; + + mmc_fix_request_block_len(card, action, arg); + access_mode_sector = (mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR) + && host->high_capacity; + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + if (access_mode_sector) { + ios.access_mode = MSS_ACCESS_MODE_SECTOR; + cmdarg = arg->block; + blklen = 512; + } + else { + if (arg->block_len != mmc_card->block_len) { + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_SET_BLOCKLEN, arg->block_len, + MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) + return ret; + mmc_card->block_len = arg->block_len; + } + cmdarg = arg->block * arg->block_len; + blklen = arg->block_len; + } + + if (mmc_card->csd.spec_vers == CSD_SPEC_VERS_4 && host->high_speed) { + ios.high_speed = MSS_HIGH_SPEED; + ios.clock = MMC_CARD_CLOCK_FAST; + } + else { + ios.clock = mmc_tran_speed(mmc_card->csd.tran_speed); + } + host->ops->set_ios(host, &ios); + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + llreq->cmd = cmd; + llreq->data = data; + +read_write_entry: + if (arg->nob > 1) { + if (action == MSS_READ_MEM) { + opcode = MMC_READ_MULTIPLE_BLOCK; + flags = MSS_DATA_READ | MSS_DATA_MULTI; + } + else { + opcode = MMC_WRITE_MULTIPLE_BLOCK; + flags = MSS_DATA_WRITE | MSS_DATA_MULTI; + } + + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (!ret) + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + + mmc_card->state = (action == MSS_WRITE_MEM) ? CARD_STATE_RCV + : CARD_STATE_DATA; + + if (ret) { + mss_send_simple_ll_req(host, llreq, cmd, + MMC_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + mmc_card->state = CARD_STATE_TRAN; + + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + ret = mss_send_simple_ll_req(host, llreq, cmd, + MMC_STOP_TRANSMISSION, 0, + (action == MSS_WRITE_MEM) ? + MSS_RESPONSE_R1B : MSS_RESPONSE_R1, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_TRAN; + + if (ret && (mmc_card->errno != MMC_ERROR_OUT_OF_RANGE)) + return ret; + } else { + if (action == MSS_READ_MEM) { + opcode = MMC_READ_SINGLE_BLOCK; + flags = MSS_DATA_READ; + } + else { + opcode = MMC_WRITE_BLOCK; + flags = MSS_DATA_WRITE; + } + MSS_INIT_CMD(cmd, opcode, cmdarg, 0, MSS_RESPONSE_R1); + MSS_INIT_DATA(data, arg->nob, blklen, flags, arg->sg_len, + arg->sg, 0); + + ret = mss_send_ll_req(host, &mmc_card->llreq); + if (!ret) + ret = mmc_unpack_r1(cmd, &r1, mmc_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < MMC_CARD_CLOCK_SLOW && retries == 1) + clock = MMC_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + } + /* Deselect the card */ + /*mmc_simple_ll_req(host, mmc_card, MMC_SELECT_CARD, + 0, MSS_RESPONSE_NONE, 0); + if (ret) + return ret; + ret = mmc_unpack_r1(&mmc_card->cmd, &r1, mmc_card); + mmc_card->state = CARD_STATE_STBY;*/ + if (ret) + return ret; + result->bytes_xfered = data->bytes_xfered; + + return MSS_ERROR_NONE; +} + +/* count by 512 bytes */ +static int mmc_get_capacity(struct mss_card *card, u32 *size) +{ + int c_size = 0; + int c_size_mult = 0; + struct mmc_card *mmc_card = card->prot_card; + struct mss_host *host = card->slot->host; + + if (mmc_card->access_mode == MMC_ACCESS_MODE_SECTOR && host->high_capacity) + *size = mmc_card->ext_csd.sec_count; + else { + c_size = mmc_card->csd.c_size; + c_size_mult = mmc_card->csd.c_size_mult; + *size = (c_size + 1) + << (2 + c_size_mult + mmc_card->csd.read_bl_len - 9); + } + dbg5("the capacity :0x%x", *size); + return MSS_ERROR_NONE; +} + + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ + +static int mmc_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + u32 status; + int ret; + + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_MMC_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = mmc_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = mmc_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg) + return -EINVAL; + ret = mmc_read_write_entry(card, action, arg, result); + break; + case MSS_QUERY_CARD: + ret = mmc_get_status(card, &status); + break; + case MSS_GET_CAPACITY: + ret = mmc_get_capacity(card, result); + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + //dbg("mmc protocol entry exit, ret: %d, action: %d\n", ret, action); + return ret; +} + +static int mmc_prot_attach_card(struct mss_card *card) +{ + struct mmc_card *mmc_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + mmc_card = kzalloc(ALIGN32(ALIGN32(sizeof(struct mmc_card))) + 512, + GFP_KERNEL); + card->prot_card = mmc_card; + if (mmc_card) { + mmc_card->buf = (char *)ALIGN32((unsigned int)&mmc_card[1]); + return 0; + } + return -ENOMEM; +} + +static void mmc_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int mmc_prot_get_errno(struct mss_card *card) +{ + struct mmc_card *mmc_card = card->prot_card; + return mmc_card->errno; +} + +static struct mss_prot_driver mmc_protocol = { + .name = MMC_PROTOCOL, + .prot_entry = mmc_prot_entry, + .attach_card = mmc_prot_attach_card, + .detach_card = mmc_prot_detach_card, + .get_errno = mmc_prot_get_errno, +}; + +static int mmc_protocol_init(void) +{ + register_mss_prot_driver(&mmc_protocol); + return 0; +} + +static void mmc_protocol_exit(void) +{ + unregister_mss_prot_driver(&mmc_protocol); +} + + +module_init(mmc_protocol_init); +module_exit(mmc_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MMC protocol driver"); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/Makefile +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the kernel MSS(mmc/sd/sdio) device drivers. +# + +# Core +obj-$(CONFIG_MSS) += mss_core.o mmc_protocol.o sdio_protocol.o sd_protocol.o + +# Media drivers +obj-$(CONFIG_MSS_BLOCK) += mss_block.o + +# Host drivers +obj-$(CONFIG_MSS_SDHCI) += mss_sdhci.o + --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/sdio_protocol.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/sdio_protocol.c @@ -0,0 +1,1094 @@ +/* + * sdio_protocol.c - SDIO protocol driver + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/***************************************************************************** + * + * internal functions + * + ****************************************************************************/ + +#define KBPS 1 +#define MBPS 1000 + +static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; +static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, + 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; + +static u32 sdio_tran_speed( u8 ts ) +{ + u32 clock = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; + + dbg5("clock :%d", clock); + return clock; +} + +static int sdio_unpack_r1(struct mss_cmd *cmd, struct sdio_response_r1 *r1, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + //debug(" result in r1: %d\n", request->result); + //if ( request->result ) return request->result; + + sdio_card->errno = SDIO_ERROR_NONE; + r1->cmd = unstuff_bits(buf, 40, 8, 6); + r1->status = unstuff_bits(buf, 8, 32, 6); + + dbg5("status 0x%x", r1->status); + if (R1_STATUS(r1->status)) { + if (r1->status & R1_OUT_OF_RANGE) + sdio_card->errno = SDIO_ERROR_OUT_OF_RANGE; + if (r1->status & R1_COM_CRC_ERROR) + sdio_card->errno = SDIO_ERROR_COM_CRC; + if (r1->status & R1_ILLEGAL_COMMAND) + sdio_card->errno = SDIO_ERROR_ILLEGAL_COMMAND; + if (r1->status & R1_ERROR) + sdio_card->errno = SDIO_ERROR_GENERAL; + } + + if (r1->cmd != cmd->opcode) + sdio_card->errno = SDIO_ERROR_HEADER_MISMATCH; + dbg5("command:0x%x", r1->cmd); + /* This should be last - it's the least dangerous error */ + if (sdio_card->errno != SDIO_ERROR_NONE) + return MSS_ERROR_RESP_UNPACK; + return MSS_ERROR_NONE; +} + + +static int sdio_unpack_r4(struct mss_cmd *cmd, struct sdio_response_r4 *r4, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + r4->ocr = unstuff_bits(buf, 8, 24, 6); + r4->ready = unstuff_bits(buf, 39, 1, 6); + r4->mem_present = unstuff_bits(buf, 35, 1, 6); + r4->func_num = unstuff_bits(buf, 36, 3, 6); + dbg5("ocr=%08x,ready=%d,mp=%d,fun_num:%d\n", r4->ocr, r4->ready, +r4->mem_present, r4->func_num); + return 0; +} + + +static int sdio_unpack_r5(struct mss_cmd *cmd, struct sdio_response_r5 *r5, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + + sdio_card->errno = SDIO_ERROR_NONE; + r5->cmd = unstuff_bits(buf, 40, 8, 6); + r5->status = unstuff_bits(buf, 16, 8, 6); + r5->data = unstuff_bits(buf, 8, 8, 6); + dbg5("cmd=%d status=%02x,data:%02x", r5->cmd, r5->status, r5->data); + + if (r5->status) { + if (r5->status & R5_OUT_OF_RANGE) + return SDIO_ERROR_OUT_OF_RANGE; + if (r5->status & R5_COM_CRC_ERROR) + return SDIO_ERROR_COM_CRC; + if (r5->status & R5_ILLEGAL_COMMAND) + return SDIO_ERROR_ILLEGAL_COMMAND; + if (r5->status & R5_ERROR) + return SDIO_ERROR_GENERAL; + if (r5->status & R5_FUNCTION_NUMBER) + return SDIO_ERROR_FUNC_NUM; + } + + if (r5->cmd != cmd->opcode) { + return SDIO_ERROR_HEADER_MISMATCH; + } + + return 0; +} + +static u16 sdio_unpack_r6(struct mss_cmd *cmd, struct sdio_response_r6 *r6, struct sdio_card *sdio_card) +{ + u8 *buf = cmd->response; + int errno = SDIO_ERROR_NONE; + + r6->cmd = unstuff_bits(buf, 40, 8, 6); + r6->rca = unstuff_bits(buf, 24, 16, 6); + r6->status = unstuff_bits(buf, 8, 16, 6); + if (R6_STATUS(r6->status)) { + if (r6->status & R6_COM_CRC_ERROR) + errno = SDIO_ERROR_COM_CRC; + if (r6->status & R6_ILLEGAL_COMMAND) + errno = SDIO_ERROR_ILLEGAL_COMMAND; + if (r6->status & R6_ERROR) + errno = SDIO_ERROR_GENERAL; + } + if (r6->cmd != cmd->opcode) + errno = SDIO_ERROR_HEADER_MISMATCH; + sdio_card->errno = errno; + if (errno) + return MSS_ERROR_RESP_UNPACK; + return 0 ; + +} + + +/***************************************************************************** + * + * internal functions + * + ****************************************************************************/ + +/* sdio related function */ +static u32 sdio_make_cmd52_arg(int rw, int fun_num, int raw, int address, int write_data) +{ + u32 ret; + dbg5("rw:%d,fun:%d,raw:%d,address:%d,write_data:%d\n", + rw, fun_num, raw, address, write_data); + ret = (rw << 31) | (fun_num << 28) | (raw << 27) | (address << 9) | write_data; + return ret; +} + +static u32 sdio_make_cmd53_arg(int rw, int fun_num, int block_mode, int op_code, int address, int count) +{ + u32 ret; + dbg5("rw:%d,fun:%d,block_mode:%d,op_code:%d,address:%d,count:%d\n", + rw, fun_num, block_mode, op_code, address, count); + ret = (rw << 31) | (fun_num << 28) | (block_mode << 27) | (op_code << 26) | (address << 9) | count; + return ret; +} + +#define SDIO_FN0_READ_REG(addr) \ + do { \ + arg = sdio_make_cmd52_arg(SDIO_R, 0, 0, addr, 0); \ + ret = mss_send_simple_ll_req(host, llreq, cmd, \ + IO_RW_DIRECT, arg, MSS_RESPONSE_R5, \ + MSS_CMD_SDIO_EN); \ + if (ret) { \ + dbg5("CMD ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + ret = sdio_unpack_r5(cmd, &r5, sdio_card); \ + if (ret) { \ + dbg5("UNPACK ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + } while(0) + +#define SDIO_FN0_WRITE_REG(addr, val) \ + do { \ + arg = sdio_make_cmd52_arg(SDIO_W, 0, 0, addr, val); \ + ret = mss_send_simple_ll_req(host, llreq, cmd, \ + IO_RW_DIRECT, arg, MSS_RESPONSE_R5, \ + MSS_CMD_SDIO_EN); \ + if (ret) { \ + dbg5("CMD ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + ret = sdio_unpack_r5(cmd, &r5, sdio_card); \ + if (ret) { \ + dbg5("UNPACK ERROR: ret = %d\n", ret); \ + return ret; \ + } \ + } while(0) + + +static int sdio_set_bus_width(struct mss_card *card, u8 buswidth) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + + SDIO_FN0_WRITE_REG(BUS_IF_CTRL, buswidth); + card->bus_width = MSS_BUSWIDTH_4BIT; + + return 0; +} + +static int sdio_set_block_size(struct mss_card *card, u16 size, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + u8 tmp; + + if (func == 0) { + tmp = size & 0xff; + SDIO_FN0_WRITE_REG(FN0_BLKSZ_1, tmp); + + tmp = (size & 0xff00) >> 8; + SDIO_FN0_WRITE_REG(FN0_BLKSZ_2, tmp); + + sdio_card->cccr.fn0_blksz = size; + } else { + tmp = size & 0xff; + SDIO_FN0_WRITE_REG(FNn_BLKSZ_1(func), tmp); + + tmp = (size & 0xff00) >> 8; + SDIO_FN0_WRITE_REG(FNn_BLKSZ_2(func), tmp); + + sdio_card->fbr[func].fn_blksz = size; + } + + return 0; +} + +static int sdio_io_enable(struct mss_card *card, u8 set_mask) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + + SDIO_FN0_WRITE_REG(IO_ENABLE, set_mask); + + return 0; +} + +static int sdio_interrupt_enable(struct mss_card *card, u8 set_mask) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + + SDIO_FN0_WRITE_REG(INT_ENABLE, set_mask); + + return 0; +} + +static int sdio_csa_enable(struct mss_card *card, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int arg; + int ret = 0; + + if(sdio_card->fbr[func].fun_support_csa == 0) + return ret; + + SDIO_FN0_WRITE_REG(FNn_IF_CODE(func), 0x80); + + return 0; +} + + +static int get_sdio_fbr_info(struct mss_card *card, int func) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret,arg; + u32 tmp; + + dbg5("get_sdio_fbr_info"); + SDIO_FN0_READ_REG(FNn_IF_CODE(func)); + sdio_card->fbr[func].fun_if_code = r5.data & 0xF; + sdio_card->fbr[func].fun_support_csa = (r5.data >> 6) & 0x1; + sdio_card->fbr[func].fun_csa_enable = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(FNn_EXT_IF_CODE(func)); + sdio_card->fbr[func].fun_ext_if_code = r5.data; + + SDIO_FN0_READ_REG(FNn_CIS_POINTER_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_CIS_POINTER_2(func)); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(FNn_CIS_POINTER_3(func)); + tmp |= r5.data << 16; + sdio_card->fbr[func].pfcis = tmp; + + SDIO_FN0_READ_REG(FNn_CSA_POINTER_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_CSA_POINTER_2(func)); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(FNn_CSA_POINTER_3(func)); + tmp |= r5.data << 16; + sdio_card->fbr[func].pcsa = tmp; + + SDIO_FN0_READ_REG(FNn_BLKSZ_1(func)); + tmp = r5.data; + SDIO_FN0_READ_REG(FNn_BLKSZ_2(func)); + tmp |= r5.data << 8; + sdio_card->fbr[func].fn_blksz = tmp; + + dbg5("func:%d, csa:0x%x, cis:0x%x, blksz:0x%x", func, sdio_card->fbr[func].pcsa, sdio_card->fbr[func].pfcis, sdio_card->fbr[func].fn_blksz); + + return 0; +} + +static int get_sdio_cccr_info(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + int ret, arg; + u32 tmp; + + dbg5("get_sdio_cccr_info"); + SDIO_FN0_READ_REG(CCCR_SDIO_REVISION); + sdio_card->cccr.sdiox = (r5.data >> 4) & 0xf; + sdio_card->cccr.cccrx = r5.data & 0xf; + + SDIO_FN0_READ_REG(SD_SPEC_REVISION); + sdio_card->cccr.sdx = r5.data & 0xf; + + SDIO_FN0_READ_REG(IO_ENABLE); + sdio_card->cccr.ioex = r5.data; + + SDIO_FN0_READ_REG(IO_READY); + sdio_card->cccr.iorx = r5.data; + + SDIO_FN0_READ_REG(INT_ENABLE); + sdio_card->cccr.intex = r5.data; + + SDIO_FN0_READ_REG(INT_PENDING); + sdio_card->cccr.intx = r5.data; + + SDIO_FN0_READ_REG(BUS_IF_CTRL); + sdio_card->cccr.buswidth = r5.data & 0x3; + sdio_card->cccr.cd = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(CARD_CAPABILITY); + sdio_card->cccr.sdc = r5.data & 0x1; + sdio_card->cccr.smb = (r5.data >> 1) & 0x1; + sdio_card->cccr.srw = (r5.data >> 2) & 0x1; + sdio_card->cccr.sbs = (r5.data >> 3) & 0x1; + sdio_card->cccr.s4mi = (r5.data >> 4) & 0x1; + sdio_card->cccr.e4mi = (r5.data >> 5) & 0x1; + sdio_card->cccr.lsc = (r5.data >> 6) & 0x1; + sdio_card->cccr.ls4b = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_1); + tmp = r5.data; + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_2); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(COMMON_CIS_POINTER_3); + tmp |= r5.data << 16; + sdio_card->cccr.pccis = tmp; + + SDIO_FN0_READ_REG(BUS_SUSPEND); + sdio_card->cccr.bs = r5.data & 0x1; + sdio_card->cccr.br = (r5.data >> 1) & 0x1; + + SDIO_FN0_READ_REG(FUNCTION_SELECT); + sdio_card->cccr.fsx = r5.data & 0xf; + sdio_card->cccr.df = (r5.data >> 7) & 0x1; + + SDIO_FN0_READ_REG(EXEC_FLAGS); + sdio_card->cccr.exx = r5.data; + + SDIO_FN0_READ_REG(READY_FLAGS); + sdio_card->cccr.rfx = r5.data; + + SDIO_FN0_READ_REG(FN0_BLKSZ_1); + tmp = r5.data; + SDIO_FN0_READ_REG(FN0_BLKSZ_2); + tmp |= r5.data << 8; + sdio_card->cccr.fn0_blksz = tmp; + + SDIO_FN0_READ_REG(POWER_CTRL); + sdio_card->cccr.smpc = r5.data & 0x1; + sdio_card->cccr.empc = (r5.data >> 1) & 0x1; + + dbg5("cccr, card capability: low_speed_card:%d" + " low_speed_card_4bit:%d int_bw_block:%d\n" + " suspend/resume:%d read/wait:%d multiblcok:%d direct_cmd:%d\n", + sdio_card->cccr.lsc, sdio_card->cccr.ls4b, + sdio_card->cccr.s4mi, sdio_card->cccr.sbs, + sdio_card->cccr.srw, sdio_card->cccr.smb, sdio_card->cccr.sdc); + dbg5("sdio:%d, sd:%d, cccr:%d, common cis:0x%x\n", sdio_card->cccr.sdiox, sdio_card->cccr.sdx, sdio_card->cccr.cccrx, sdio_card->cccr.pccis); + dbg5("spmc:%d\n", sdio_card->cccr.smpc); + dbg5("ioe:0x%x, ior:0x%x\n", sdio_card->cccr.ioex, sdio_card->cccr.iorx); + return 0; +} + +static int get_sdio_fcis_info(struct mss_card *card, int func) +{ + struct mss_host *host= card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + int ret, arg, tuple_body_len, tuple_type; + struct sdio_response_r5 r5; + u32 addr, next_addr; + u32 tmp; + u16 tmp16; + + dbg5("get_sdio_fcis_info"); + addr = sdio_card->fbr[func].pfcis; + + while(1) { + SDIO_FN0_READ_REG(addr); + tuple_type = r5.data; + + SDIO_FN0_READ_REG(addr + 1); + tuple_body_len = r5.data; + + next_addr = addr + 2 + r5.data; + switch (tuple_type) { + case CISTPL_NULL: + case CISTPL_END: + dbg5("cistpl null/end\n"); + goto finish; + case CISTPL_CHECKSUM: + dbg5("cistpl checksum\n"); + break; + case CISTPL_VERS_1: + dbg5("cistpl vers level 1\n"); + break; + case CISTPL_ALTSTR: + dbg5("cistpl altstr\n"); + break; + case CISTPL_MANFID: + dbg5("cistpl manfid\n"); + break; + case CISTPL_FUNCID: + dbg5("cistpl funcid\n"); + SDIO_FN0_READ_REG(addr + 2); + + if (r5.data != 0x0c) + dbg5("not a sdio card\n"); + else + dbg5(" a sdio card\n"); + + break; + case CISTPL_FUNCE: + /* Type of extended data, should be 1 */ + SDIO_FN0_READ_REG(addr + 2); + if (r5.data == 0x01) + dbg5("1 type extended tuple\n"); + + /* FUNCTION_INFO */ + SDIO_FN0_READ_REG(addr + 3); + sdio_card->fcis[func].func_info = r5.data; + + /* STD_IO_REV */ + SDIO_FN0_READ_REG(addr + 4); + sdio_card->fcis[func].std_io_rev = r5.data; + + /* card psn */ + SDIO_FN0_READ_REG(addr + 5); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 6); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 7); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 8); + tmp |= r5.data << 24; + sdio_card->fcis[func].card_psn = tmp; + + /* card csa size */ + SDIO_FN0_READ_REG(addr + 9); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 10); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 11); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 12); + tmp |= r5.data << 24; + sdio_card->fcis[func].csa_size = tmp; + + /* csa property */ + SDIO_FN0_READ_REG(addr + 13); + sdio_card->fcis[func].csa_property = r5.data; + + /* max_blk_size */ + SDIO_FN0_READ_REG(addr + 14); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 15); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].max_blk_size = tmp16; + + /* ocr */ + SDIO_FN0_READ_REG(addr + 16); + tmp = r5.data; + SDIO_FN0_READ_REG(addr + 17); + tmp |= r5.data << 8; + SDIO_FN0_READ_REG(addr + 18); + tmp |= r5.data << 16; + SDIO_FN0_READ_REG(addr + 19); + tmp |= r5.data << 24; + sdio_card->fcis[func].ocr = tmp; + + /* pwr */ + SDIO_FN0_READ_REG(addr + 20); + sdio_card->fcis[func].op_min_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 21); + sdio_card->fcis[func].op_avg_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 22); + sdio_card->fcis[func].op_max_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 23); + sdio_card->fcis[func].sb_min_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 24); + sdio_card->fcis[func].sb_avg_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 25); + sdio_card->fcis[func].sb_max_pwr = r5.data; + + SDIO_FN0_READ_REG(addr + 26); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 27); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].min_bw = tmp16; + + SDIO_FN0_READ_REG(addr + 28); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 29); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].opt_bw = tmp16; + + // SDIO1.0 is 28, and 1.1 is 36 + if (sdio_card->cccr.sdiox == 0) + break; + SDIO_FN0_READ_REG(addr + 30); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 31); + tmp16 |= r5.data << 8; + sdio_card->fcis[func].enable_timeout_val= tmp16; + break; + case CISTPL_SDIO_STD: + dbg5("sdio std\n"); + break; + case CISTPL_SDIO_EXT: + dbg5("sdio std ext\n"); + break; + default : + dbg5("not supported cis\n"); + } + addr = next_addr; + } +finish: + dbg5("fcis %d\nfunction_info:0x%x std_io_rev:0x%x card_psn:0x%x\n" + "csa_size:0x%x csa_property:0x%x max_blk_size:0x%x\n" + "ocr:0x%x op_min_pwr:0x%x op_avg_pwr:0x%x op_max_pwr:0x%x" + "sb_min_pwr:0x%x sb_avg_pwr:0x%x sb_max_pwr:0x%x" + "min_bw:0x%x opt_bw:0x%x time out:%x\n",func, + sdio_card->fcis[func].func_info, sdio_card->fcis[func].std_io_rev, sdio_card->fcis[func].card_psn, + sdio_card->fcis[func].csa_size, sdio_card->fcis[func].csa_property, sdio_card->fcis[func].max_blk_size, + sdio_card->fcis[func].ocr, sdio_card->fcis[func].op_min_pwr, sdio_card->fcis[func].op_avg_pwr, sdio_card->fcis[func].op_max_pwr, + sdio_card->fcis[func].sb_min_pwr, sdio_card->fcis[func].sb_avg_pwr, sdio_card->fcis[func].sb_max_pwr, + sdio_card->fcis[func].min_bw, sdio_card->fcis[func].opt_bw, sdio_card->fcis[func].enable_timeout_val); + return 0; +} + +static int get_sdio_ccis_info(struct mss_card *card) +{ + struct mss_host *host= card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + int ret, arg, tuple_body_len, tuple_type; + struct sdio_response_r5 r5; + u32 addr, next_addr; + u16 tmp16; + + dbg5("get_sdio_ccis_info"); + addr = sdio_card->cccr.pccis; + while (1) { + SDIO_FN0_READ_REG(addr); + tuple_type = r5.data; + + SDIO_FN0_READ_REG(addr + 1); + tuple_body_len = r5.data; + next_addr = addr + 2 + r5.data; + + switch (tuple_type) { + case CISTPL_NULL: + case CISTPL_END: + dbg5("cistpl null/end\n"); + goto finish; + case CISTPL_CHECKSUM: + dbg5("cistpl checksum\n"); + break; + case CISTPL_VERS_1: + dbg5("cistpl vers level 1\n"); + break; + case CISTPL_ALTSTR: + dbg5("cistpl altstr\n"); + break; + case CISTPL_MANFID: + dbg5("cistpl manfid\n"); + SDIO_FN0_READ_REG(addr + 2); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 3); + tmp16 |= r5.data << 8; + sdio_card->ccis.manufacturer = tmp16; + + SDIO_FN0_READ_REG(addr + 4); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 5); + tmp16 |= r5.data << 8; + sdio_card->ccis.card_id = tmp16; + + break; + case CISTPL_FUNCID: + dbg5("cistpl funcid\n"); + SDIO_FN0_READ_REG(addr + 2); + if (r5.data != 0x0c) + dbg5("not a sdio card\n"); + else + dbg5(" a sdio card\n"); + + break; + case CISTPL_FUNCE: + dbg5("cistpl funce\n"); + SDIO_FN0_READ_REG(addr + 2); + if (r5.data == 0x00) + dbg5("0 type extended tuple\n"); + + SDIO_FN0_READ_REG(addr + 3); + tmp16 = r5.data; + SDIO_FN0_READ_REG(addr + 4); + tmp16 = r5.data << 8; + sdio_card->ccis.fn0_block_size = tmp16; + + SDIO_FN0_READ_REG(addr + 5); + sdio_card->ccis.max_tran_speed = r5.data; + //slot->tran_speed = card->ccis.max_tran_speed; + break; + case CISTPL_SDIO_STD: + dbg5("sdio std\n"); + break; + case CISTPL_SDIO_EXT: + dbg5("sdio std ext\n"); + break; + default: + dbg5("not supported cis\n"); + } + addr = next_addr; + } +finish: + dbg5("ccis:\nmanf:0x%x card_id:0x%x block_size:0x%x\nmax_tran_speed:0x%x\n",sdio_card->ccis.manufacturer, sdio_card->ccis.card_id, sdio_card->ccis.fn0_block_size, sdio_card->ccis.max_tran_speed); + return 0; +} + +/***************************************************************************** + * + * protocol entry functions + * + ****************************************************************************/ + +static int sdio_recognize_card(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct mss_ios ios; + struct sdio_response_r4 r4; + int ret; + + card->card_type = MSS_UNKNOWN_CARD; + card->state = CARD_STATE_INIT; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + /* check if a sdio card, need not send CMD0 to reset for SDIO card */ + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + 0, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + sdio_card->func_num = r4.func_num; + sdio_card->mem_present = r4.mem_present; + if (!r4.func_num) + return MSS_ERROR_NONE; + /* maybe COMBO_CARD. but we can return SDIO_CARD first, + * in sdio_card_init, we will judge further. + */ + if(r4.ocr & host->vdd) { + card->card_type = MSS_SDIO_CARD; + } else { + printk(KERN_WARNING "uncompatible card\n"); + card->card_type = MSS_UNCOMPATIBLE_CARD; + } + + return MSS_ERROR_NONE; +} + +static int sdio_card_init(struct mss_card *card) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r1 r1; + struct sdio_response_r4 r4; + struct sdio_response_r6 r6; + struct mss_ios ios; + int ret, tmp, i; + u8 funcs; + + dbg5("card = %08X\n", (u32)card); + card->state = CARD_STATE_INIT; + card->bus_width = MSS_BUSWIDTH_1BIT; + + memcpy(&ios, &host->ios, sizeof(struct mss_ios)); + ios.clock = host->f_min; + ios.bus_width = MSS_BUSWIDTH_1BIT; + host->ops->set_ios(host, &ios); + + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + host->vdd, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + + while (!r4.ready) { + //mdelay(20); + msleep(15); + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_SEND_OP_COND, + host->vdd, MSS_RESPONSE_R4, 0); + if (ret) + return ret; + ret = sdio_unpack_r4(cmd, &r4, sdio_card); + if (ret) + return ret; + } + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SET_RELATIVE_ADDR, + 0, MSS_RESPONSE_R6, 0); + if (ret) + return ret; + ret = sdio_unpack_r6(cmd, &r6, sdio_card); + if (ret) + return ret; + sdio_card->state = CARD_STATE_STBY; + sdio_card->rca = r6.rca; + + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + (sdio_card->rca) << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sdio_unpack_r1(cmd, &r1, sdio_card); + if (ret) + return ret; + + /** CARD_STATE_CMD */ + //slot->state = CARD_STATE_CMD; + //send CMD53 to let DATA BUS FREE, since bus_suspend not supported, need not to do this + //arg = sdio_make_cmd53_arg(SDIO_READ, 0, 0, 0, 0, 1); + //mss_simple_cmd( dev, IO_RW_EXTENDED, arg, RESPONSE_R5); + + + /** CARD_STATE_TRAN */ + sdio_card->state = CARD_STATE_CMD; + + + ret = get_sdio_cccr_info(card); + if (ret) + return ret; + funcs = sdio_card->func_num; + for(i = 1; i <= funcs; i++) { + ret = get_sdio_fbr_info(card, i); + if (ret) + return ret; + } + + ret = get_sdio_ccis_info(card); + if (ret) + return ret; + for(i = 1; i <= funcs; i++) { + ret = get_sdio_fcis_info(card, i); + if (ret) + return ret; + } + if(host->bus_width == MSS_BUSWIDTH_4BIT + && (!sdio_card->cccr.lsc || sdio_card->cccr.ls4b)) { + host->ios.bus_width = MSS_BUSWIDTH_4BIT; + sdio_set_bus_width(card, 2); + } + + /* enable function */ + tmp = 0; + for(i = 1; i <= funcs; i++) { + tmp |= (1 << i); + } + ret = sdio_io_enable(card, tmp); + if (ret) + return ret; + + /* enable interrupt */ + tmp = 1; + for(i = 1; i <= funcs; i++) { + tmp |= (1 << i); + } + ret = sdio_interrupt_enable(card, tmp); + if (ret) + return ret; + + /* enable card capabilites */ + for (i=1; i <= funcs; i++) { + sdio_csa_enable(card, i); + } + + mss_set_sdio_int(card->slot->host, 1); + + return MSS_ERROR_NONE; +} + +static int sdio_read_write_entry(struct mss_card *card, int action, struct mss_rw_arg *arg, struct mss_rw_result *result) +{ + struct mss_host *host = card->slot->host; + struct sdio_card *sdio_card = card->prot_card; + struct mss_cmd *cmd = &sdio_card->cmd; + struct mss_data *data = &sdio_card->data; + struct mss_ll_request *llreq = &sdio_card->llreq; + struct sdio_response_r5 r5; + struct sdio_response_r1 r1; + int ret; + u32 addr, blkmode, func, rw, rw_count, opcode, clock, cmdarg; + int retries = 4; + + if (sdio_card->state == CARD_STATE_STBY) { + ret = mss_send_simple_ll_req(host, llreq, cmd, SD_SELECT_CARD, + sdio_card->rca << 16, MSS_RESPONSE_R1B, 0); + if (ret) + return ret; + ret = sdio_unpack_r1(cmd, &r1, sdio_card); + if (ret) + return ret; + } + + mss_set_clock(host, sdio_tran_speed(sdio_card->ccis.max_tran_speed)); + func = arg->func; + if (func > sdio_card->func_num) + return MSS_ERROR_WRONG_ARG; + + if (arg->block_len == 0) { + blkmode = 0; + } + else { + if (!sdio_card->cccr.smb) + return MSS_ERROR_WRONG_ARG; + dbg5("blkzs:%d, %d\n", arg->block_len, sdio_card->fbr[func].fn_blksz); + if (arg->block_len != sdio_card->fbr[func].fn_blksz) { + ret = sdio_set_block_size(card, arg->block_len, func); + if (ret) + return ret; + } + blkmode = 1; + } + + rw = (action == MSS_READ_MEM) ? 0 : 1; + addr = arg->block; + opcode = (arg->opcode) ? 1 : 0; + rw_count = arg->nob; + + memset(llreq, 0x0, sizeof(struct mss_ll_request)); + memset(cmd, 0x0, sizeof(struct mss_cmd)); + memset(data, 0x0, sizeof(struct mss_data)); + +read_write_entry: + /* deal with request */ + /* if only one byte, then use CMD52 to read*/ + if (!blkmode && rw_count == 1) { + u8 val = (rw) ? arg->val : 0; + dbg5("use CMD52 to transfer data. rw direction: %d", rw); + cmdarg = sdio_make_cmd52_arg(rw, func, opcode, addr, val); + + dbg5("cmdarg :0x%x\n", cmdarg); + ret = mss_send_simple_ll_req(host, llreq, cmd, IO_RW_DIRECT, + cmdarg, MSS_RESPONSE_R5, + MSS_CMD_SDIO_EN); + if (!ret) + ret = sdio_unpack_r5(cmd, &r5, sdio_card); + if (!ret) + result->bytes_xfered = r5.data; + else if (ret && --retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SDIO_CARD_CLOCK_SLOW && retries == 1) { + clock = SDIO_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + dbg5("r5.data:0x%x\n",r5.data); + } + else { + cmdarg= sdio_make_cmd53_arg(rw, func, blkmode, opcode, addr, + rw_count); + MSS_INIT_CMD(cmd, IO_RW_EXTENDED, cmdarg, MSS_CMD_SDIO_EN, + MSS_RESPONSE_R5); + MSS_INIT_DATA(data, rw_count, arg->block_len, + ((rw) ? MSS_DATA_WRITE : MSS_DATA_READ), + arg->sg_len, arg->sg, 0); + llreq->cmd = cmd; + llreq->data = data; + + ret = mss_send_ll_req(host, llreq); + if (!ret) + ret = sdio_unpack_r5(cmd, &r5, sdio_card); + if (ret) { + if (--retries) { + clock = host->ios.clock; + clock = clock >> 1; + if (clock < SDIO_CARD_CLOCK_SLOW + && retries == 1) + clock = SDIO_CARD_CLOCK_SLOW; + mss_set_clock(host, clock); + goto read_write_entry; + } + return ret; + } + + } + return MSS_ERROR_NONE; +} + +/***************************************************************************** + * + * protocol driver interface functions + * + ****************************************************************************/ + +static int sdio_prot_entry(struct mss_card *card, unsigned int action, void *arg, void *result) +{ + int ret; + + dbg5("action = %d\n", action); + if (action != MSS_RECOGNIZE_CARD && card->card_type != MSS_SDIO_CARD) + return MSS_ERROR_WRONG_CARD_TYPE; + switch (action) { + case MSS_RECOGNIZE_CARD: + ret = sdio_recognize_card(card); + break; + case MSS_INIT_CARD: + ret = sdio_card_init(card); + break; + case MSS_READ_MEM: + case MSS_WRITE_MEM: + if (!arg || !result) + return -EINVAL; + ret = sdio_read_write_entry(card, action, arg, result); + break; + case MSS_QUERY_CARD: + ret = MSS_ERROR_NONE; + break; + default: + ret = MSS_ERROR_ACTION_UNSUPPORTED; + break; + } + + return ret; +} + +static int sdio_prot_attach_card(struct mss_card *card) +{ + struct sdio_card *sdio_card; + +#define ALIGN32(x) (((x) + 31) & (~31)) + sdio_card = kzalloc(ALIGN32(sizeof(struct sdio_card)), GFP_KERNEL); + card->prot_card = sdio_card; + if (sdio_card) { + return 0; + } + return -ENOMEM; +} + +static void sdio_prot_detach_card(struct mss_card *card) +{ + kfree(card->prot_card); +} + +static int sdio_prot_get_errno(struct mss_card *card) +{ + struct sdio_card *sdio_card = card->prot_card; + + return sdio_card->errno; +} + +static struct mss_prot_driver sdio_protocol = { + .name = SDIO_PROTOCOL, + .prot_entry = sdio_prot_entry, + .attach_card = sdio_prot_attach_card, + .detach_card = sdio_prot_detach_card, + .get_errno = sdio_prot_get_errno, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int sdio_protocol_init(void) +{ + register_mss_prot_driver(&sdio_protocol); + return 0; +} + +static void sdio_protocol_exit(void) +{ + unregister_mss_prot_driver(&sdio_protocol); +} + + +module_init(sdio_protocol_init); +module_exit(sdio_protocol_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SDIO protocol driver"); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/Kconfig @@ -0,0 +1,28 @@ +# +# MMC subsystem configuration +# + +comment "MSS structure support" + + +config MSS_BLOCK + tristate "MSS block device driver" + depends on MSS && BLOCK + default y + help + Say Y here to enable the MMC block device driver support. + This provides a block device driver, which you can use to + mount the filesystem. Almost everyone wishing MMC support + should say Y or M here. + +config MSS_SDHCI + tristate "MSS host controller driver" + depends on PCI && MSS + help + This select the generic Secure Digital Host Controller Interface. + It is used by manufacturers such as Texas Instruments(R), Ricoh(R) + and Toshiba(R). Most controllers found in laptops are of this type. + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/mss/mss_block.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/mss/mss_block.c @@ -0,0 +1,555 @@ +/* + * mss_block.c - MMC/SD Card driver (block device driver) + * + * Copyright (C) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 only + * for now as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * derived from previous mmc code in Linux kernel + * Copyright (c) 2002 Hewlett-Packard Company + * Copyright (c) 2002 Andrew Christian + * Copyright (c) 2006 Bridge Wu + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +#include + +#define MSS_SHIFT 3 +#define MSS_SECTOR_SIZE (512) + +static int major; + +struct mss_disk { + struct request_queue *queue; + struct gendisk *disk; + struct mss_card *card; + struct class_device cdev; + + u32 flags; /* for suspend/resume */ +#define MSS_QUEUE_SUSPENDED (1 << 1) +#define MSS_QUEUE_EXIT (1 << 0) + struct completion thread_complete; + struct semaphore thread_sem; + wait_queue_head_t thread_wq; + spinlock_t request_lock; + struct scatterlist *sg; + struct request *req; +}; + +#define MSS_NUM_MINORS (256 << MSS_SHIFT) + +static unsigned long dev_use[MSS_NUM_MINORS/8*sizeof(unsigned long)]; + +static DECLARE_MUTEX(md_ref_mutex); + +static struct mss_disk *mss_disk_get(struct gendisk *disk) +{ + struct mss_disk *md; + + down(&md_ref_mutex); + md = disk->private_data; + if (md) { + if (mss_card_get(md->card) == 0) + class_device_get(&md->cdev); + else + md = NULL; + } + up(&md_ref_mutex); + + return md; +} + +static void mss_disk_put(struct mss_disk *md) +{ + struct mss_card *card = md->card; + + down(&md_ref_mutex); + class_device_put(&md->cdev); + mss_card_put(card); + up(&md_ref_mutex); +} + +static void mss_disk_release(struct class_device *cdev) +{ + struct mss_disk *md = container_of(cdev, struct mss_disk, cdev); + struct gendisk *disk = md->disk; + + /* Release the minor number */ + __clear_bit(disk->first_minor >> MSS_SHIFT, dev_use); + + put_disk(md->disk); + + /* Terminate the request handler thread */ + md->flags |= MSS_QUEUE_EXIT; + wake_up(&md->thread_wq); + wait_for_completion(&md->thread_complete); + + kfree(md->sg); + md->sg = NULL; + + blk_cleanup_queue(md->queue); + + put_device(&md->card->dev); + md->card = NULL; + kfree(md); +} + +static struct class mss_disk_class = { + .name = "mss disk", + .owner = THIS_MODULE, + .release = mss_disk_release, + //.class_dev_attrs = mss_disk_attrs, +}; + +static int mss_media_transfer(struct mss_disk *md, struct request *req) +{ + struct mss_request mreq; + struct mss_rw_arg marg; + struct mss_rw_result mres; + int ret; + + memset(&mreq, 0x0, sizeof(mreq)); + memset(&marg, 0x0, sizeof(marg)); + memset(&mres, 0x0, sizeof(marg)); + + mreq.arg = &marg; + mreq.result = &mres; + mreq.card = md->card; + do { + if (rq_data_dir(req) == READ) + mreq.action = MSS_READ_MEM; + else + mreq.action = MSS_WRITE_MEM; + + marg.nob = req->nr_sectors; + /* FIXME */ + marg.block_len = MSS_SECTOR_SIZE; + marg.block = req->sector; + marg.sg = md->sg; + marg.sg_len = blk_rq_map_sg(req->q, req, marg.sg); + + ret = mss_send_request(&mreq); + if (ret) + goto err; + dbg5("successful, bytes transfer :%x\n", mres.bytes_xfered); + ret = end_that_request_chunk(req, 1, mres.bytes_xfered); + if (!ret) { + add_disk_randomness(md->disk); + blkdev_dequeue_request(req); + end_that_request_last(req, 0); + } + } while (ret); + + return 1; +err: + dbg5("error, bytes transfer :%x\n", mres.bytes_xfered); + do { + ret = end_that_request_chunk(req, 0, + req->current_nr_sectors << 9); + } while (ret); + + add_disk_randomness(md->disk); + blkdev_dequeue_request(req); + end_that_request_last(req, 0); + + return 0; +} + +static int mss_queue_thread(void *d) +{ + struct mss_disk *md = d; + DECLARE_WAITQUEUE(wait, current); + + current->flags |= PF_MEMALLOC; + + daemonize("mmcqd%d", md->disk->first_minor >> MSS_SHIFT); + + complete(&md->thread_complete); + + down(&md->thread_sem); + add_wait_queue(&md->thread_wq, &wait); + do { + struct request *req = NULL; + + + /* masked by Feng */ + /* try_to_freeze(); */ + spin_lock_irq(&md->request_lock); + set_current_state(TASK_INTERRUPTIBLE); + if (!blk_queue_plugged(md->queue)) + md->req = req = elv_next_request(md->queue); + spin_unlock_irq(&md->request_lock); + + if (!req) { + if (md->flags & MSS_QUEUE_EXIT) + break; + up(&md->thread_sem); + schedule(); + down(&md->thread_sem); + continue; + } + set_current_state(TASK_RUNNING); + + mss_media_transfer(md, req); + } while (1); + remove_wait_queue(&md->thread_wq, &wait); + up(&md->thread_sem); + + complete_and_exit(&md->thread_complete, 0); + return 0; +} + +static int mss_media_preq(struct request_queue *q, struct request *req) +{ + struct mss_disk *md = q->queuedata; + if (!md || !md->card || + (md->card->state & (MSS_CARD_REMOVING | MSS_CARD_INVALID))) { + return BLKPREP_KILL; + } + return BLKPREP_OK; +} + + +/** + * mss_media_request + * @q: request queue + * + * entry function to request handling of MMC/SD block device driver. + * handle a request from request queue generated by upper layer. + */ +static void mss_media_request(request_queue_t *q) +{ + struct mss_disk *md = q->queuedata; + + if (md && !md->req) + wake_up(&md->thread_wq); +} + + +static int mss_blk_open(struct inode *inode, struct file *filp) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct mss_disk *md; + + md = mss_disk_get(disk); + if (!md) + return -ENXIO; + + if ((filp->f_mode & FMODE_WRITE) && (md->card->state & MSS_CARD_WP)) + return -EROFS; + /* FIXME check media change */ + check_disk_change(inode->i_bdev); + return 0; +} + +static int mss_blk_release(struct inode *inode, struct file *filep) +{ + struct gendisk *disk = inode->i_bdev->bd_disk; + struct mss_disk *md = disk->private_data; + + mss_disk_put(md); + return 0; +} + +static struct block_device_operations mss_bdops = { + .open = mss_blk_open, + .release = mss_blk_release, + //.media_changed = mss_media_changed, + //.revalidate_disk = mss_media_revalidate_disk, + .owner = THIS_MODULE, +}; + +/***************************************************************************** + * + * device driver functions + * + ****************************************************************************/ + +/** + * mss_card_probe + * @dev: device + * + * probe method to initialize block device. + * initialize mss_block_device, set capacity, load block driver(add_disk). + * + * invoked by bus_match (invoked by device_register or driver_register) + * must have device and driver, or this function cannot be invoked. + */ +static int mss_blk_probe(struct device *dev) +{ + struct mss_disk *md; + struct mss_card *card; + struct mss_host *host; + int devidx, ret = 0; + u64 limit = BLK_BOUNCE_HIGH; + + dbg5("read to probe card"); + devidx = find_first_zero_bit(dev_use, MSS_NUM_MINORS); + if (devidx >= MSS_NUM_MINORS) { + printk(KERN_ERR "can not find available minors"); + return -ENOSPC; + } + __set_bit(devidx, dev_use); + + card = container_of(dev, struct mss_card, dev); + + host = card->slot->host; + if (card->card_type != MSS_MMC_CARD && card->card_type != MSS_SD_CARD) { + printk(KERN_ERR "card(slot%d, host%d) is not memory card\n", + card->slot->id, host->id); + ret = -ENOTBLK; + goto clear_bit; + } + + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (!md) { + printk(KERN_ERR "card(slot%d, host%d) alloc block_dev failed!" + "\n", card->slot->id, host->id); + ret = -ENOMEM; + goto clear_bit; + } + md->card = card; + md->disk = alloc_disk(1 << MSS_SHIFT); + if (md->disk == NULL) { + printk(KERN_ERR "card(slot%d, host%d) alloc disk failed!\n", + card->slot->id, host->id); + ret = -ENOMEM; + goto free_data; + } + md->disk->major = major; + md->disk->first_minor = devidx << MSS_SHIFT; + md->disk->fops = &mss_bdops; + md->disk->driverfs_dev = &card->dev; + md->disk->private_data = md; +// sprintf(md->disk->devfs_name, "mssblk%d", devidx); + sprintf(md->disk->disk_name, "mss/blk%d", devidx); + + class_device_initialize(&md->cdev); + md->cdev.dev = &card->dev; + md->cdev.class = &mss_disk_class; + strncpy(md->cdev.class_id, card->dev.bus_id, BUS_ID_SIZE); + ret = class_device_add(&md->cdev); + if (ret) { + goto free_disk; + } + get_device(&card->dev); + + spin_lock_init(&md->request_lock); + md->queue = blk_init_queue(mss_media_request, &md->request_lock); + if (!md->queue) { + ret = -ENOMEM; + goto remove_cdev; + } + if (host->dev->dma_mask && *host->dev->dma_mask) + limit = *host->dev->dma_mask; + + blk_queue_prep_rq(md->queue, mss_media_preq); + blk_queue_bounce_limit(md->queue, limit); + blk_queue_max_sectors(md->queue, host->max_sectors); + blk_queue_max_phys_segments(md->queue, host->max_phys_segs); + blk_queue_max_hw_segments(md->queue, host->max_hw_segs); + blk_queue_max_segment_size(md->queue, host->max_seg_size); + + md->queue->queuedata = md; + + md->sg = kmalloc(sizeof(struct scatterlist) * host->max_phys_segs, + GFP_KERNEL); + if (!md->sg) { + ret = -ENOMEM; + goto clean_queue; + } + + init_completion(&md->thread_complete); + init_waitqueue_head(&md->thread_wq); + init_MUTEX(&md->thread_sem); + + ret = kernel_thread(mss_queue_thread, md, CLONE_KERNEL); + if (ret < 0) { + goto free_sg; + } + wait_for_completion(&md->thread_complete); + init_completion(&md->thread_complete); + + md->disk->queue = md->queue; + dev_set_drvdata(dev, md); + blk_queue_hardsect_size(md->queue, MSS_SECTOR_SIZE); + set_capacity(md->disk, mss_get_capacity(card)/(MSS_SECTOR_SIZE/512) - 4); + add_disk(md->disk); + return 0; + +free_sg: + kfree(md->sg); +clean_queue: + blk_cleanup_queue(md->queue); +remove_cdev: + class_device_del(&md->cdev); + put_device(&card->dev); +free_disk: + put_disk(md->disk); +free_data: + kfree(md); +clear_bit: + __clear_bit(devidx, dev_use); + + return ret; +} + +/** + * mss_card_remove + * @dev: device + * + * remove method to remove block device. + * invoked by device_unregister or driver_unregister. + */ +static int mss_blk_remove(struct device *dev) +{ + struct mss_disk *md; + struct mss_card *card; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + class_device_del(&md->cdev); + del_gendisk(md->disk); + md->disk->queue = NULL; + + down(&md_ref_mutex); + dev_set_drvdata(dev, NULL); + class_device_put(&md->cdev); + up(&md_ref_mutex); + + return 0; +} + +/** + * mss_card_suspend + * @dev: device + * @state: suspend state + * @level: suspend level + * + * card specific suspend. + * invoke blk_stop_queue to suspend request queue. + */ +static int mss_blk_suspend(struct device *dev, pm_message_t state)//, u32 level) +{ + struct mss_disk *md; + struct mss_card *card; + unsigned long flags; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + if (!(md->flags & MSS_QUEUE_SUSPENDED)) { + md->flags |= MSS_QUEUE_SUSPENDED; + spin_lock_irqsave(&md->request_lock, flags); + blk_stop_queue(md->queue); + spin_unlock_irqrestore(&md->request_lock, flags); + } + + return 0; +} + +/** + * mss_card_resume + * @dev: device + * @level: suspend level + * + * card specific resume. + * invoke blk_start_queue to resume request queue. + */ +static int mss_blk_resume(struct device *dev)//, u32 level) +{ + struct mss_disk *md; + struct mss_card *card; + unsigned long flags; + + card = container_of(dev, struct mss_card, dev); + md = dev_get_drvdata(dev); + + if (md->flags & MSS_QUEUE_SUSPENDED) { + md->flags &= ~MSS_QUEUE_SUSPENDED; + spin_lock_irqsave(&md->request_lock, flags); + blk_start_queue(md->queue); + spin_unlock_irqrestore(&md->request_lock, flags); + } + + return 0; +} + +static struct mss_driver mss_block_driver = { + .driver = { + .name = "MMC_SD Block Driver", + .probe = mss_blk_probe, + .remove = mss_blk_remove, + .suspend = mss_blk_suspend, + .resume = mss_blk_resume, + }, +}; + +/***************************************************************************** + * + * module init and exit functions + * + ****************************************************************************/ +static int mss_card_driver_init(void) +{ + int ret = -ENOMEM; + + ret = register_blkdev(major, "mmc"); + if (ret < 0) { + printk(KERN_ERR "Unable to get major %d for MMC media: %d\n", + major, ret); + return ret; + } + if (major == 0) + major = ret; + + dbg5("Get major number :%d\n", major); +// devfs_mk_dir("mmc"); + + class_register(&mss_disk_class); + return register_mss_driver(&mss_block_driver); +} + +static void mss_card_driver_exit(void) +{ + unregister_mss_driver(&mss_block_driver); +// devfs_remove("mmc"); + unregister_blkdev(major, "mmc"); + class_unregister(&mss_disk_class); +} + + +module_init(mss_card_driver_init); +module_exit(mss_card_driver_exit); + +MODULE_AUTHOR("Bridge Wu"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Block device driver for MMC/SD card"); --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/Makefile +++ linux-source-2.6.22-2.6.22/drivers/mmc/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_MMC) += core/ obj-$(CONFIG_MMC) += card/ obj-$(CONFIG_MMC) += host/ +obj-$(CONFIG_MSS) += mss/ --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/mmc/Kconfig @@ -2,6 +2,8 @@ # MMC subsystem configuration # +menu "MMC/SD/SDIO support, can only select one arch from MMC and MSS" + menuconfig MMC tristate "MMC/SD card support" depends on HAS_IOMEM @@ -17,7 +19,6 @@ help This is an option for use by developers; most people should say N here. This enables MMC core and driver debugging. - if MMC source "drivers/mmc/core/Kconfig" @@ -27,3 +28,22 @@ source "drivers/mmc/host/Kconfig" endif # MMC + +config MSS + tristate "MSS architecture MMC/SD/SDIO Interface support" + help + MSS is an advanced version of the MMC protocol drivers + which abstracts the control layer to encompass multiple + media card formats. Simply define the protocols you + wish to use (one is MMC for instance, another is SD). + + If you want MSS support, you should say M here and also + to the specific drivers for your MSS interface. + +if MSS + +source "drivers/mmc/mss/Kconfig" + +endif + +endmenu --- linux-source-2.6.22-2.6.22.orig/drivers/mmc/host/sdhci.c +++ linux-source-2.6.22-2.6.22/drivers/mmc/host/sdhci.c @@ -34,6 +34,7 @@ /* Controller doesn't like some resets when there is no card inserted. */ #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) +#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) static const struct pci_device_id pci_ids[] __devinitdata = { { @@ -70,6 +71,32 @@ .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, }, + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB714_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB714_SD_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, @@ -751,6 +778,14 @@ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); + /* + * Some (ENE) controllers go apeshit on some ios operation, + * signalling timeout and CRC errors even on CMD0. Resetting + * it on each ios seems to solve the problem. + */ + if(host->chip->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) + sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } --- linux-source-2.6.22-2.6.22.orig/drivers/char/keyboard.c +++ linux-source-2.6.22-2.6.22/drivers/char/keyboard.c @@ -1027,6 +1027,8 @@ int code; switch (keycode) { + case KEY_RESERVED: + break; case KEY_PAUSE: put_queue(vc, 0xe1); put_queue(vc, 0x1d | up_flag); @@ -1086,6 +1088,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag) { + if (keycode == KEY_RESERVED) + return 0; if (keycode > 127) return -1; --- linux-source-2.6.22-2.6.22.orig/drivers/char/random.c +++ linux-source-2.6.22-2.6.22/drivers/char/random.c @@ -693,9 +693,14 @@ if (r->pull && r->entropy_count < nbytes * 8 && r->entropy_count < r->poolinfo->POOLBITS) { - int bytes = max_t(int, random_read_wakeup_thresh / 8, - min_t(int, nbytes, sizeof(tmp))); + /* If we're limited, always leave two wakeup worth's BITS */ int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4; + int bytes = nbytes; + + /* pull at least as many as BYTES as wakeup BITS */ + bytes = max_t(int, bytes, random_read_wakeup_thresh / 8); + /* but never more than the buffer size */ + bytes = min_t(int, bytes, sizeof(tmp)); DEBUG_ENT("going to reseed %s with %d bits " "(%d of %d requested)\n", @@ -1545,11 +1550,13 @@ * As close as possible to RFC 793, which * suggests using a 250 kHz clock. * Further reading shows this assumes 2 Mb/s networks. - * For 10 Gb/s Ethernet, a 1 GHz clock is appropriate. - * That's funny, Linux has one built in! Use it! - * (Networks are faster now - should this be increased?) + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but + * we also need to limit the resolution so that the u32 seq + * overlaps less than one time per MSL (2 minutes). + * Choosing a clock of 64 ns period is OK. (period of 274 s) */ - seq += ktime_get_real().tv64; + seq += ktime_get_real().tv64 >> 6; #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", saddr, daddr, sport, dport, seq); --- linux-source-2.6.22-2.6.22.orig/drivers/char/mspec.c +++ linux-source-2.6.22-2.6.22/drivers/char/mspec.c @@ -265,7 +265,8 @@ vdata->refcnt = ATOMIC_INIT(1); vma->vm_private_data = vdata; - vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED | VM_PFNMAP); + vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED | VM_PFNMAP | + VM_DONTEXPAND); if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_ops = &mspec_vm_ops; --- linux-source-2.6.22-2.6.22.orig/drivers/char/rtc.c +++ linux-source-2.6.22-2.6.22/drivers/char/rtc.c @@ -1159,7 +1159,8 @@ spin_unlock_irq(&rtc_lock); - printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); + if (printk_ratelimit()) + printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); /* Now we have new data */ wake_up_interruptible(&rtc_wait); --- linux-source-2.6.22-2.6.22.orig/drivers/char/agp/intel-agp.c +++ linux-source-2.6.22-2.6.22/drivers/char/agp/intel-agp.c @@ -20,7 +20,9 @@ #define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2 #define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00 #define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02 +#define PCI_DEVICE_ID_INTEL_82965GME_HB 0x2A10 #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 +#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 @@ -33,7 +35,8 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ @@ -505,7 +508,7 @@ break; } } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: gtt_entries = MB(1) - KB(size); break; @@ -527,6 +530,7 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || IS_I965 || IS_G33) gtt_entries = MB(48) - KB(size); else @@ -538,6 +542,7 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || IS_I965 || IS_G33) gtt_entries = MB(64) - KB(size); else @@ -1848,9 +1853,9 @@ NULL, &intel_915_driver }, { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G", NULL, &intel_915_driver }, - { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM", + { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 0, "945GM", NULL, &intel_915_driver }, - { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME", + { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME", NULL, &intel_915_driver }, { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", NULL, &intel_i965_driver }, @@ -1860,9 +1865,9 @@ NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G", NULL, &intel_i965_driver }, - { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM", + { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 0, "965GM", NULL, &intel_i965_driver }, - { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE", + { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL }, { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL }, @@ -2051,11 +2056,13 @@ ID(PCI_DEVICE_ID_INTEL_82915GM_HB), ID(PCI_DEVICE_ID_INTEL_82945G_HB), ID(PCI_DEVICE_ID_INTEL_82945GM_HB), + ID(PCI_DEVICE_ID_INTEL_82945GME_HB), ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), ID(PCI_DEVICE_ID_INTEL_82965Q_HB), ID(PCI_DEVICE_ID_INTEL_82965G_HB), ID(PCI_DEVICE_ID_INTEL_82965GM_HB), + ID(PCI_DEVICE_ID_INTEL_82965GME_HB), ID(PCI_DEVICE_ID_INTEL_G33_HB), ID(PCI_DEVICE_ID_INTEL_Q35_HB), ID(PCI_DEVICE_ID_INTEL_Q33_HB), --- linux-source-2.6.22-2.6.22.orig/drivers/char/agp/agp.h +++ linux-source-2.6.22-2.6.22/drivers/char/agp/agp.h @@ -176,7 +176,7 @@ #define I830_GMCH_MEM_MASK 0x1 #define I830_GMCH_MEM_64M 0x1 #define I830_GMCH_MEM_128M 0 -#define I830_GMCH_GMS_MASK 0xF0 +#define I830_GMCH_GMS_MASK 0x70 #define I830_GMCH_GMS_DISABLED 0x00 #define I830_GMCH_GMS_LOCAL 0x10 #define I830_GMCH_GMS_STOLEN_512 0x20 @@ -190,6 +190,7 @@ #define INTEL_I830_ERRSTS 0x92 /* Intel 855GM/852GM registers */ +#define I855_GMCH_GMS_MASK 0xF0 #define I855_GMCH_GMS_STOLEN_0M 0x0 #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) --- linux-source-2.6.22-2.6.22.orig/drivers/char/sx.c +++ linux-source-2.6.22-2.6.22/drivers/char/sx.c @@ -2721,9 +2721,9 @@ its because the standard requires it. So check for SUBVENDOR_ID. */ static struct pci_device_id sx_pci_tbl[] = { { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = 0x0200,.subdevice = PCI_ANY_ID }, + .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = 0x0300,.subdevice = PCI_ANY_ID }, + .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, { 0 } }; --- linux-source-2.6.22-2.6.22.orig/drivers/char/drm/i915_irq.c +++ linux-source-2.6.22-2.6.22/drivers/char/drm/i915_irq.c @@ -214,6 +214,10 @@ drm_device_t *dev = (drm_device_t *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; + u32 pipea_stats, pipeb_stats; + + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); temp = I915_READ16(I915REG_INT_IDENTITY_R); @@ -225,6 +229,8 @@ return IRQ_NONE; I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -252,6 +258,12 @@ if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; --- linux-source-2.6.22-2.6.22.orig/drivers/char/drm/i915_dma.c +++ linux-source-2.6.22-2.6.22/drivers/char/drm/i915_dma.c @@ -184,6 +184,8 @@ * private backbuffer/depthbuffer usage. */ dev_priv->use_mi_batchbuffer_start = 0; + if (IS_I965G(dev)) /* 965 doesn't support older method */ + dev_priv->use_mi_batchbuffer_start = 1; /* Allow hardware batchbuffers unless told otherwise. */ @@ -517,8 +519,13 @@ if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); + if (IS_I965G(dev)) { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); + OUT_RING(batch->start); + } else { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); + OUT_RING(batch->start | MI_BATCH_NON_SECURE); + } ADVANCE_LP_RING(); } else { BEGIN_LP_RING(4); @@ -735,7 +742,8 @@ switch (param.param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - dev_priv->use_mi_batchbuffer_start = param.value; + if (!IS_I965G(dev)) + dev_priv->use_mi_batchbuffer_start = param.value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: dev_priv->tex_lru_log_granularity = param.value; --- linux-source-2.6.22-2.6.22.orig/drivers/char/drm/i915_drv.h +++ linux-source-2.6.22-2.6.22/drivers/char/drm/i915_drv.h @@ -210,6 +210,12 @@ #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 +#define I915REG_PIPEASTAT 0x70024 +#define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) + #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 @@ -282,6 +288,7 @@ #define MI_BATCH_BUFFER_START (0x31<<23) #define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_BATCH_NON_SECURE_I965 (1<<8) #define MI_WAIT_FOR_EVENT ((0x3<<23)) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) --- linux-source-2.6.22-2.6.22.orig/drivers/char/drm/drm_vm.c +++ linux-source-2.6.22-2.6.22/drivers/char/drm/drm_vm.c @@ -520,6 +520,7 @@ vma->vm_ops = &drm_vm_dma_ops; vma->vm_flags |= VM_RESERVED; /* Don't swap */ + vma->vm_flags |= VM_DONTEXPAND; vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open_locked(vma); @@ -669,6 +670,7 @@ return -EINVAL; /* This should never happen. */ } vma->vm_flags |= VM_RESERVED; /* Don't swap */ + vma->vm_flags |= VM_DONTEXPAND; vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open_locked(vma); --- linux-source-2.6.22-2.6.22.orig/drivers/char/vt.c +++ linux-source-2.6.22-2.6.22/drivers/char/vt.c @@ -234,6 +234,10 @@ #define DO_UPDATE(vc) CON_IS_VISIBLE(vc) #endif +#ifdef CONFIG_PROM_CONSOLE +static int force_prom_console; +#endif + static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) { unsigned short *p; @@ -2836,6 +2840,17 @@ .unthrottle = con_unthrottle, }; +#ifdef CONFIG_PROM_CONSOLE +static int __init check_prom_console(char *str) +{ + force_prom_console = 1; + printk ("PROM console forced!\n"); + return 1; +} + +__setup("forcepromconsole", check_prom_console); +#endif + int __init vty_init(void) { vcs_init(); @@ -2858,7 +2873,8 @@ kbd_init(); console_map_init(); #ifdef CONFIG_PROM_CONSOLE - prom_con_init(); + if (force_prom_console) + prom_con_init(); #endif #ifdef CONFIG_MDA_CONSOLE mda_console_init(); --- linux-source-2.6.22-2.6.22.orig/drivers/media/dvb/b2c2/flexcop-i2c.c +++ linux-source-2.6.22-2.6.22/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -135,6 +135,13 @@ struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); int i, ret = 0; + /* Some drivers use 1 byte or 0 byte reads as probes, which this + * driver doesn't support. These probes will always fail, so this + * hack makes them always succeed. If one knew how, it would of + * course be better to actually do the read. */ + if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1) + return 1; + if (mutex_lock_interruptible(&fc->i2c_mutex)) return -ERESTARTSYS; --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-driver.h +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-driver.h @@ -650,7 +650,6 @@ /* convenience pointer to sliced struct in vbi_in union */ struct v4l2_sliced_vbi_format *sliced_in; u32 service_set_in; - u32 service_set_out; int insert_mpeg; /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. @@ -723,6 +722,7 @@ int search_pack_header; spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ + struct mutex serialize_lock; /* lock used to serialize starting streams */ /* User based DMA for OSD */ struct ivtv_user_dma udma; --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-driver.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-driver.c @@ -622,6 +622,7 @@ itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ + mutex_init(&itv->serialize_lock); mutex_init(&itv->i2c_bus_lock); mutex_init(&itv->udma.lock); --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-vbi.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-vbi.c @@ -219,31 +219,23 @@ int found_cc = 0; int cc_pos = itv->vbi.cc_pos; - if (itv->vbi.service_set_out == 0) - return -EPERM; - while (count >= sizeof(struct v4l2_sliced_vbi_data)) { switch (p->id) { case V4L2_SLICED_CAPTION_525: - if (p->id == V4L2_SLICED_CAPTION_525 && - p->line == 21 && - (itv->vbi.service_set_out & - V4L2_SLICED_CAPTION_525) == 0) { - break; - } - found_cc = 1; - if (p->field) { - cc[2] = p->data[0]; - cc[3] = p->data[1]; - } else { - cc[0] = p->data[0]; - cc[1] = p->data[1]; + if (p->line == 21) { + found_cc = 1; + if (p->field) { + cc[2] = p->data[0]; + cc[3] = p->data[1]; + } else { + cc[0] = p->data[0]; + cc[1] = p->data[1]; + } } break; case V4L2_SLICED_VPS: - if (p->line == 16 && p->field == 0 && - (itv->vbi.service_set_out & V4L2_SLICED_VPS)) { + if (p->line == 16 && p->field == 0) { itv->vbi.vps[0] = p->data[2]; itv->vbi.vps[1] = p->data[8]; itv->vbi.vps[2] = p->data[9]; @@ -255,8 +247,7 @@ break; case V4L2_SLICED_WSS_625: - if (p->line == 23 && p->field == 0 && - (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) { + if (p->line == 23 && p->field == 0) { /* No lock needed for WSS */ itv->vbi.wss = p->data[0] | (p->data[1] << 8); itv->vbi.wss_found = 1; --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-ioctl.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1183,6 +1183,7 @@ itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + ivtv_set_osd_alpha(itv); break; } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-irq.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-irq.c @@ -403,6 +403,11 @@ /* Mark last buffer size for Interrupt flag */ s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); + if (s->type == IVTV_ENC_STREAM_TYPE_VBI) + set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); + else + clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); + if (ivtv_use_pio(s)) { for (i = 0; i < s->SG_length; i++) { s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); @@ -597,7 +602,6 @@ data[0], data[1], data[2]); return; } - clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); s = &itv->streams[ivtv_stream_map[data[0]]]; if (!stream_enc_dma_append(s, data)) { set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); @@ -634,7 +638,6 @@ then start a DMA request for just the VBI data. */ if (!stream_enc_dma_append(s, data) && !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { - set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); } } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/ivtv/ivtv-streams.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/ivtv/ivtv-streams.c @@ -446,6 +446,9 @@ if (s->v4l2dev == NULL) return -EINVAL; + /* Big serialization lock to ensure no two streams are started + simultaneously: that can give all sorts of weird results. */ + mutex_lock(&itv->serialize_lock); IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); switch (s->type) { @@ -487,6 +490,7 @@ 0, sizeof(itv->vbi.sliced_mpeg_size)); break; default: + mutex_unlock(&itv->serialize_lock); return -EINVAL; } s->subtype = subtype; @@ -568,6 +572,7 @@ if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) { IVTV_DEBUG_WARN( "Error starting capture!\n"); + mutex_unlock(&itv->serialize_lock); return -EINVAL; } @@ -583,6 +588,7 @@ /* you're live! sit back and await interrupts :) */ atomic_inc(&itv->capturing); + mutex_unlock(&itv->serialize_lock); return 0; } @@ -762,17 +768,6 @@ /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); - /* only run these if we're shutting down the last cap */ - if (atomic_read(&itv->capturing) - 1 == 0) { - /* event notification (off) */ - if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { - /* type: 0 = refresh */ - /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ - ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); - ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); - } - } - then = jiffies; if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { @@ -840,17 +835,30 @@ /* Clear capture and no-read bits */ clear_bit(IVTV_F_S_STREAMING, &s->s_flags); + /* ensure these global cleanup actions are done only once */ + mutex_lock(&itv->serialize_lock); + if (s->type == IVTV_ENC_STREAM_TYPE_VBI) ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); if (atomic_read(&itv->capturing) > 0) { + mutex_unlock(&itv->serialize_lock); return 0; } /* Set the following Interrupt mask bits for capture */ ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); + /* event notification (off) */ + if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { + /* type: 0 = refresh */ + /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ + ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); + ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); + } + wake_up(&s->waitq); + mutex_unlock(&itv->serialize_lock); return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/v4l2-common.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/v4l2-common.c @@ -939,16 +939,25 @@ When no more controls are available 0 is returned. */ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) { - u32 ctrl_class; + u32 ctrl_class = V4L2_CTRL_ID2CLASS(id); const u32 *pctrl; - /* if no query is desired, then just return the control ID */ - if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) - return id; if (ctrl_classes == NULL) return 0; + + /* if no query is desired, then check if the ID is part of ctrl_classes */ + if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) { + /* find class */ + while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class) + ctrl_classes++; + if (*ctrl_classes == NULL) + return 0; + pctrl = *ctrl_classes; + /* find control ID */ + while (*pctrl && *pctrl != id) pctrl++; + return *pctrl ? id : 0; + } id &= V4L2_CTRL_ID_MASK; - ctrl_class = V4L2_CTRL_ID2CLASS(id); id++; /* select next control */ /* find first class that matches (or is greater than) the class of the ID */ --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/wm8739.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/wm8739.c @@ -321,12 +321,14 @@ static int wm8739_detach(struct i2c_client *client) { + struct wm8739_state *state = i2c_get_clientdata(client); int err; err = i2c_detach_client(client); if (err) return err; + kfree(state); kfree(client); return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/pwc/pwc-if.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/pwc/pwc-if.c @@ -1196,12 +1196,19 @@ return 0; } + +static void pwc_cleanup(struct pwc_device *pdev) +{ + pwc_remove_sysfs_files(pdev->vdev); + video_unregister_device(pdev->vdev); +} + /* Note that all cleanup is done in the reverse order as in _open */ static int pwc_video_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - int i; + int i, hint; PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); @@ -1224,8 +1231,9 @@ pwc_isoc_cleanup(pdev); pwc_free_buffers(pdev); + lock_kernel(); /* Turn off LEDS and power down camera, but only when not unplugged */ - if (pdev->error_status != EPIPE) { + if (!pdev->unplugged) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); @@ -1234,9 +1242,19 @@ if (i < 0) PWC_ERROR("Failed to power down camera (%d)\n", i); } + pdev->vopen--; + PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + } else { + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; } - pdev->vopen--; - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + unlock_kernel(); + return 0; } @@ -1791,21 +1809,21 @@ /* Alert waiting processes */ wake_up_interruptible(&pdev->frameq); /* Wait until device is closed */ - while (pdev->vopen) - schedule(); - /* Device is now closed, so we can safely unregister it */ - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); - pwc_remove_sysfs_files(pdev->vdev); - video_unregister_device(pdev->vdev); - - /* Free memory (don't set pdev to 0 just yet) */ - kfree(pdev); + if(pdev->vopen) { + pdev->unplugged = 1; + } else { + /* Device is closed, so we can safely unregister it */ + PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); disconnect_out: - /* search device_hint[] table if we occupy a slot, by any chance */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) - if (device_hint[hint].pdev == pdev) - device_hint[hint].pdev = NULL; + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; + } unlock_kernel(); } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/pwc/pwc.h +++ linux-source-2.6.22-2.6.22/drivers/media/video/pwc/pwc.h @@ -193,6 +193,7 @@ char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ char vmirror; /* for ToUCaM series */ + char unplugged; int cmd_len; unsigned char cmd_buf[13]; --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/cx88/cx88-mpeg.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/cx88/cx88-mpeg.c @@ -580,7 +580,7 @@ list_for_each(list,&cx8802_devlist) { h = list_entry(list, struct cx8802_dev, devlist); - if (h->mpeg_dev->minor == minor) + if (h->mpeg_dev && h->mpeg_dev->minor == minor) return h; } --- linux-source-2.6.22-2.6.22.orig/drivers/media/video/wm8775.c +++ linux-source-2.6.22-2.6.22/drivers/media/video/wm8775.c @@ -222,12 +222,14 @@ static int wm8775_detach(struct i2c_client *client) { + struct wm8775_state *state = i2c_get_clientdata(client); int err; err = i2c_detach_client(client); if (err) { return err; } + kfree(state); kfree(client); return 0; --- linux-source-2.6.22-2.6.22.orig/drivers/message/fusion/mptbase.c +++ linux-source-2.6.22-2.6.22/drivers/message/fusion/mptbase.c @@ -2567,6 +2567,16 @@ pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); + /* + * VMware emulation is broken, its PortFact's MaxDevices reports value + * programmed by IOC Init, so if you program IOC Init to 256 (which is 0, + * as that field is only 8 bit), it reports back 0 in port facts, instead + * of 256... And unfortunately using 256 triggers another bug in the + * code (parallel SCSI can have only 16 devices). + */ + if (pfacts->MaxDevices == 0) { + pfacts->MaxDevices = 16; + } pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); --- linux-source-2.6.22-2.6.22.orig/drivers/kvm/svm.c +++ linux-source-2.6.22-2.6.22/drivers/kvm/svm.c @@ -1727,6 +1727,12 @@ static int is_disabled(void) { + u64 vm_cr; + + rdmsrl(MSR_VM_CR, vm_cr); + if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE)) + return 1; + return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/kvm/svm.h +++ linux-source-2.6.22-2.6.22/drivers/kvm/svm.h @@ -175,8 +175,11 @@ #define SVM_CPUID_FUNC 0x8000000a #define MSR_EFER_SVME_MASK (1ULL << 12) +#define MSR_VM_CR 0xc0010114 #define MSR_VM_HSAVE_PA 0xc0010117ULL +#define SVM_VM_CR_SVM_DISABLE 4 + #define SVM_SELECTOR_S_SHIFT 4 #define SVM_SELECTOR_DPL_SHIFT 5 #define SVM_SELECTOR_P_SHIFT 7 --- linux-source-2.6.22-2.6.22.orig/drivers/pcmcia/cs.c +++ linux-source-2.6.22-2.6.22/drivers/pcmcia/cs.c @@ -409,6 +409,9 @@ #endif s->functions = 0; + /* give socket some time to power down */ + msleep(100); + s->ops->get_status(s, &status); if (status & SS_POWERON) { printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); @@ -560,7 +563,10 @@ if (!(skt->state & SOCKET_PRESENT)) { skt->state &= ~SOCKET_SUSPEND; - return socket_insert(skt); + /* UBUNTU: This causes problems on resume. Userspace + * scripts take care of this. */ + /* return socket_insert(skt); */ + return 0; } ret = socket_setup(skt, resume_delay); --- linux-source-2.6.22-2.6.22.orig/drivers/macintosh/mediabay.c +++ linux-source-2.6.22-2.6.22/drivers/macintosh/mediabay.c @@ -447,6 +447,7 @@ return -ENODEV; } +EXPORT_SYMBOL(check_media_bay_by_base); int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, int irq, int index) @@ -487,6 +488,7 @@ return -ENODEV; } +EXPORT_SYMBOL(media_bay_set_ide_infos); static void media_bay_step(int i) { --- linux-source-2.6.22-2.6.22.orig/drivers/usb/storage/scsiglue.c +++ linux-source-2.6.22-2.6.22/drivers/usb/storage/scsiglue.c @@ -177,6 +177,10 @@ * is an occasional series of retries that will all fail. */ sdev->retry_hwerror = 1; + /* USB disks should allow restart. Some drives spin down + * automatically, requiring a START-STOP UNIT command. */ + sdev->allow_restart = 1; + } else { /* Non-disk-type devices don't need to blacklist any pages --- linux-source-2.6.22-2.6.22.orig/drivers/usb/storage/unusual_devs.h +++ linux-source-2.6.22-2.6.22/drivers/usb/storage/unusual_devs.h @@ -313,6 +313,20 @@ US_SC_DEVICE, US_PR_DEVICE,NULL, US_FL_NOT_LOCKABLE ), +/* Reported by Stefan de Konink */ +UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, + "NIKON", + "NIKON DSC D100", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Reported by Milinevsky Dmitry */ +UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, + "NIKON", + "NIKON DSC D50", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Andreas Bockhold */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -327,13 +341,27 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported by Graber and Mike Pagano */ +UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200, + "NIKON", + "NIKON DSC D200", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Emil Larsson */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100, +UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, "NIKON", "NIKON DSC D80", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported by Ortwin Glueck */ +UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0110, + "NIKON", + "NIKON DSC D40", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* BENQ DC5330 * Reported by Manuel Fombuena and * Frank Copeland */ @@ -1473,6 +1501,11 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_CAPACITY_HEURISTICS), +UNUSUAL_DEV( 0Xed10, 0x7636, 0x0001, 0x0001, + "TGE", + "Digital MP3 Audio Player", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/io_edgeport.c +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/io_edgeport.c @@ -2366,9 +2366,8 @@ int status; unsigned char number = edge_port->port->number - edge_port->port->serial->minor; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) { dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", edge_port->port->number, baudRate); return 0; @@ -2461,18 +2460,16 @@ dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && - (regNum == MCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && + regNum == MCR) { dbg("SendCmdWriteUartReg - Not writing to MCR Register"); return 0; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && - (regNum == LCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteLCR && + regNum == LCR) { dbg ("SendCmdWriteUartReg - Not writing to LCR Register"); return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/ftdi_sio.c +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/ftdi_sio.c @@ -271,26 +271,58 @@ static __u16 vendor = FTDI_VID; static __u16 product; +struct ftdi_private { + ftdi_chip_type_t chip_type; + /* type of the device, either SIO or FT8U232AM */ + int baud_base; /* baud base clock for divisor setting */ + int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ + __u16 last_set_data_urb_value ; + /* the last data state set - needed for doing a break */ + int write_offset; /* This is the offset in the usb data block to write the serial data - + * it is different between devices + */ + int flags; /* some ASYNC_xxxx flags are supported */ + unsigned long last_dtr_rts; /* saved modem control outputs */ + wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ + char prev_status, diff_status; /* Used for TIOCMIWAIT */ + __u8 rx_flags; /* receive state flags (throttling) */ + spinlock_t rx_lock; /* spinlock for receive state */ + struct delayed_work rx_work; + struct usb_serial_port *port; + int rx_processed; + unsigned long rx_bytes; + + __u16 interface; /* FT2232C port interface (0 for FT232/245) */ + + int force_baud; /* if non-zero, force the baud rate to this value */ + int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ + + spinlock_t tx_lock; /* spinlock for transmit state */ + unsigned long tx_bytes; + unsigned long tx_outstanding_bytes; + unsigned long tx_outstanding_urbs; +}; + /* struct ftdi_sio_quirk is used by devices requiring special attention. */ struct ftdi_sio_quirk { int (*probe)(struct usb_serial *); - void (*setup)(struct usb_serial *); /* Special settings during startup. */ + void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */ }; static int ftdi_olimex_probe (struct usb_serial *serial); -static void ftdi_USB_UIRT_setup (struct usb_serial *serial); -static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); +static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); +static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); static struct ftdi_sio_quirk ftdi_olimex_quirk = { .probe = ftdi_olimex_probe, }; static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { - .setup = ftdi_USB_UIRT_setup, + .port_probe = ftdi_USB_UIRT_setup, }; static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { - .setup = ftdi_HE_TIRA1_setup, + .port_probe = ftdi_HE_TIRA1_setup, }; /* @@ -567,38 +599,6 @@ #define THROTTLED 0x01 #define ACTUALLY_THROTTLED 0x02 -struct ftdi_private { - ftdi_chip_type_t chip_type; - /* type of the device, either SIO or FT8U232AM */ - int baud_base; /* baud base clock for divisor setting */ - int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ - __u16 last_set_data_urb_value ; - /* the last data state set - needed for doing a break */ - int write_offset; /* This is the offset in the usb data block to write the serial data - - * it is different between devices - */ - int flags; /* some ASYNC_xxxx flags are supported */ - unsigned long last_dtr_rts; /* saved modem control outputs */ - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - char prev_status, diff_status; /* Used for TIOCMIWAIT */ - __u8 rx_flags; /* receive state flags (throttling) */ - spinlock_t rx_lock; /* spinlock for receive state */ - struct delayed_work rx_work; - struct usb_serial_port *port; - int rx_processed; - unsigned long rx_bytes; - - __u16 interface; /* FT2232C port interface (0 for FT232/245) */ - - int force_baud; /* if non-zero, force the baud rate to this value */ - int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ - - spinlock_t tx_lock; /* spinlock for transmit state */ - unsigned long tx_bytes; - unsigned long tx_outstanding_bytes; - unsigned long tx_outstanding_urbs; -}; - /* Used for TIOCMIWAIT */ #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) @@ -609,7 +609,6 @@ /* function prototypes for a FTDI serial converter */ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); -static int ftdi_sio_attach (struct usb_serial *serial); static void ftdi_shutdown (struct usb_serial *serial); static int ftdi_sio_port_probe (struct usb_serial_port *port); static int ftdi_sio_port_remove (struct usb_serial_port *port); @@ -663,7 +662,6 @@ .ioctl = ftdi_ioctl, .set_termios = ftdi_set_termios, .break_ctl = ftdi_break_ctl, - .attach = ftdi_sio_attach, .shutdown = ftdi_shutdown, }; @@ -1198,6 +1196,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) { struct ftdi_private *priv; + struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); + dbg("%s",__FUNCTION__); @@ -1214,6 +1214,9 @@ than queue a task to deliver them */ priv->flags = ASYNC_LOW_LATENCY; + if (quirk && quirk->port_probe) + quirk->port_probe(priv); + /* Increase the size of read buffers */ kfree(port->bulk_in_buffer); port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL); @@ -1244,29 +1247,13 @@ return 0; } -/* attach subroutine */ -static int ftdi_sio_attach (struct usb_serial *serial) -{ - /* Check for device requiring special set up. */ - struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial); - - if (quirk && quirk->setup) - quirk->setup(serial); - - return 0; -} /* ftdi_sio_attach */ - - /* Setup for the USB-UIRT device, which requires hardwired * baudrate (38400 gets mapped to 312500) */ /* Called from usbserial:serial_probe */ -static void ftdi_USB_UIRT_setup (struct usb_serial *serial) +static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) { - struct ftdi_private *priv; - dbg("%s",__FUNCTION__); - priv = usb_get_serial_port_data(serial->port[0]); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 77; priv->force_baud = B38400; @@ -1274,13 +1261,10 @@ /* Setup for the HE-TIRA1 device, which requires hardwired * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ -static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) +static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) { - struct ftdi_private *priv; - dbg("%s",__FUNCTION__); - priv = usb_get_serial_port_data(serial->port[0]); priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 240; priv->force_baud = B38400; --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/sierra.c +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/sierra.c @@ -41,10 +41,12 @@ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ + { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ + { USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600 ZTE MF330 */ { } }; MODULE_DEVICE_TABLE(usb, id_table); @@ -52,6 +54,7 @@ static struct usb_device_id id_table_1port [] = { { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ + { USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600 ZTE MF330 */ { } }; @@ -67,6 +70,7 @@ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ + { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ { } }; --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/airprime.c +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/airprime.c @@ -19,6 +19,8 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ + { USB_DEVICE(0x0930, 0x1303) }, /* Toshiba (Novatel Wireless) HSDPA for M400 */ + { USB_DEVICE(0x106c, 0x3702) }, /* Sprint Pantech PX-500 DGE */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/pl2303.h +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/pl2303.h @@ -59,6 +59,7 @@ #define SIEMENS_PRODUCT_ID_SX1 0x0001 #define SIEMENS_PRODUCT_ID_X65 0x0003 #define SIEMENS_PRODUCT_ID_X75 0x0004 +#define SIEMENS_PRODUCT_ID_EF81 0x0005 #define SYNTECH_VENDOR_ID 0x0745 #define SYNTECH_PRODUCT_ID 0x0001 @@ -102,3 +103,6 @@ #define WS002IN_VENDOR_ID 0x11f6 #define WS002IN_PRODUCT_ID 0x2001 +/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ +#define SANWA_VENDOR_ID 0x11ad +#define SANWA_PRODUCT_ID 0x0001 --- linux-source-2.6.22-2.6.22.orig/drivers/usb/serial/pl2303.c +++ linux-source-2.6.22-2.6.22/drivers/usb/serial/pl2303.c @@ -73,6 +73,7 @@ { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) }, { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, @@ -84,6 +85,7 @@ { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { } /* Terminating entry */ }; --- linux-source-2.6.22-2.6.22.orig/drivers/usb/core/message.c +++ linux-source-2.6.22-2.6.22/drivers/usb/core/message.c @@ -623,12 +623,12 @@ memset(buf,0,size); // Make sure we parse really received data for (i = 0; i < 3; ++i) { - /* retry on length 0 or stall; some devices are flakey */ + /* retry on length 0 or error; some devices are flakey */ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, USB_CTRL_GET_TIMEOUT); - if (result == 0 || result == -EPIPE) + if (result <= 0 && result != -ETIMEDOUT) continue; if (result > 1 && ((u8 *)buf)[1] != type) { result = -EPROTO; @@ -1344,6 +1344,30 @@ usb_dev = interface_to_usbdev(intf); alt = intf->cur_altsetting; +#ifdef CONFIG_USB_DEVICEFS + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "DEVICE=/proc/bus/usb/%03d/%03d", + usb_dev->bus->busnum, usb_dev->devnum)) + return -ENOMEM; +#endif + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "PRODUCT=%x/%x/%x", + le16_to_cpu(usb_dev->descriptor.idVendor), + le16_to_cpu(usb_dev->descriptor.idProduct), + le16_to_cpu(usb_dev->descriptor.bcdDevice))) + return -ENOMEM; + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "TYPE=%d/%d/%d", + usb_dev->descriptor.bDeviceClass, + usb_dev->descriptor.bDeviceSubClass, + usb_dev->descriptor.bDeviceProtocol)) + return -ENOMEM; + if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "INTERFACE=%d/%d/%d", --- linux-source-2.6.22-2.6.22.orig/drivers/usb/core/hcd.h +++ linux-source-2.6.22-2.6.22/drivers/usb/core/hcd.h @@ -19,6 +19,8 @@ #ifdef __KERNEL__ +#include + /* This file contains declarations of usbcore internals that are mostly * used or exposed by Host Controller Drivers. */ @@ -464,5 +466,9 @@ : (in_interrupt () ? "in_interrupt" : "can sleep")) -#endif /* __KERNEL__ */ +/* Mutual exclusion for EHCI CF initialization. This interferes with + * port reset on some companion controllers. + */ +extern struct rw_semaphore ehci_cf_port_reset_rwsem; +#endif /* __KERNEL__ */ --- linux-source-2.6.22-2.6.22.orig/drivers/usb/core/hub.c +++ linux-source-2.6.22-2.6.22/drivers/usb/core/hub.c @@ -117,6 +117,12 @@ "try the other device initialization scheme if the " "first one fails"); +/* Mutual exclusion for EHCI CF initialization. This interferes with + * port reset on some companion controllers. + */ +DECLARE_RWSEM(ehci_cf_port_reset_rwsem); +EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); + static inline char *portspeed(int portstatus) { @@ -1388,6 +1394,10 @@ udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); + /* Increment the parent's count of unsuspended children */ + if (udev->parent) + usb_autoresume_device(udev->parent); + /* Register the device. The device driver is responsible * for adding the device files to sysfs and for configuring * the device. @@ -1395,13 +1405,11 @@ err = device_add(&udev->dev); if (err) { dev_err(&udev->dev, "can't device_add, error %d\n", err); + if (udev->parent) + usb_autosuspend_device(udev->parent); goto fail; } - /* Increment the parent's count of unsuspended children */ - if (udev->parent) - usb_autoresume_device(udev->parent); - exit: return err; @@ -1511,6 +1519,8 @@ { int i, status; + down_read(&ehci_cf_port_reset_rwsem); + /* Reset the port */ for (i = 0; i < PORT_RESET_TRIES; i++) { status = set_port_feature(hub->hdev, @@ -1541,7 +1551,7 @@ usb_set_device_state(udev, status ? USB_STATE_NOTATTACHED : USB_STATE_DEFAULT); - return status; + goto done; } dev_dbg (hub->intfdev, @@ -1554,6 +1564,8 @@ "Cannot enable port %i. Maybe the USB cable is bad?\n", port1); + done: + up_read(&ehci_cf_port_reset_rwsem); return status; } --- linux-source-2.6.22-2.6.22.orig/drivers/usb/core/driver.c +++ linux-source-2.6.22-2.6.22/drivers/usb/core/driver.c @@ -58,7 +58,7 @@ dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; spin_lock(&dynids->lock); - list_add_tail(&dynids->list, &dynid->node); + list_add_tail(&dynid->node, &dynids->list); spin_unlock(&dynids->lock); if (get_driver(driver)) { --- linux-source-2.6.22-2.6.22.orig/drivers/usb/core/quirks.c +++ linux-source-2.6.22-2.6.22/drivers/usb/core/quirks.c @@ -30,10 +30,52 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + + /* BenQ */ + /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ + { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Acer Peripherals Inc. (now BenQ Corp.) S2W 3300U/4300U */ + { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* Canon */ + /* CanoScan N650U/N656U */ + { USB_DEVICE(0x04a9, 0x2206), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan 1220U */ + { USB_DEVICE(0x04a9, 0x2207), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* CanoScan N1240U/LiDE 30 */ + { USB_DEVICE(0x04a9, 0x220e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* CanoScan N670U/N676U/LiDE 20 */ + { USB_DEVICE(0x04a9, 0x220d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon LiDE25 */ + { USB_DEVICE(0x04a9, 0x2220), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* Epson */ + /* Seiko Epson Corp. Perfection 1200 */ + { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp. Perfection 660 */ + { USB_DEVICE(0x04b8, 0x0114), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Epson Perfection 1260 Photo */ + { USB_DEVICE(0x04b8, 0x011d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp - Perfection 1670 */ { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp - Perfection 2480 */ + { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* Samsung ML-2510 Series printer */ + { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Elsa MicroLink 56k (V.250) */ { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Ultima Electronics Corp. */ + { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* RIM Blackberry */ + { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + { USB_DEVICE(0x0fca, 0x0006), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* Umax [hex] Astra 3400U */ + { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, { } /* terminating entry must be last */ }; @@ -75,4 +117,10 @@ /* do any special quirk handling here if needed */ if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND) usb_autosuspend_quirk(udev); + + /* By default, disable autosuspend for all non-hubs */ +#ifdef CONFIG_USB_SUSPEND + if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) + udev->autosuspend_delay = -1; +#endif } --- linux-source-2.6.22-2.6.22.orig/drivers/usb/class/cdc-acm.c +++ linux-source-2.6.22-2.6.22/drivers/usb/class/cdc-acm.c @@ -919,6 +919,10 @@ return -EINVAL; } } + + /* Accept probe requests only for the control interface */ + if (intf != control_interface) + return -ENODEV; if (usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev,"The data interface isn't available"); @@ -1107,10 +1111,12 @@ return; } if (acm->country_codes){ - device_remove_file(&intf->dev, &dev_attr_wCountryCodes); - device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&acm->control->dev, + &dev_attr_iCountryCodeRelDate); } - device_remove_file(&intf->dev, &dev_attr_bmCapabilities); + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); acm->dev = NULL; usb_set_intfdata(acm->control, NULL); usb_set_intfdata(acm->data, NULL); @@ -1172,6 +1178,9 @@ { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0e8d,0x0003), /* MediaTek Inc MT6227 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, --- linux-source-2.6.22-2.6.22.orig/drivers/usb/host/ehci-hcd.c +++ linux-source-2.6.22-2.6.22/drivers/usb/host/ehci-hcd.c @@ -567,9 +567,11 @@ * involved with the root hub. (Except where one is integrated, * and there's no companion controller unless maybe for USB OTG.) */ + down_write(&ehci_cf_port_reset_rwsem); hcd->state = HC_STATE_RUNNING; ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + up_write(&ehci_cf_port_reset_rwsem); temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci_info (ehci, --- linux-source-2.6.22-2.6.22.orig/drivers/mtd/mtdpart.c +++ linux-source-2.6.22-2.6.22/drivers/mtd/mtdpart.c @@ -560,7 +560,3 @@ EXPORT_SYMBOL_GPL(parse_mtd_partitions); EXPORT_SYMBOL_GPL(register_mtd_parser); EXPORT_SYMBOL_GPL(deregister_mtd_parser); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nicolas Pitre "); -MODULE_DESCRIPTION("Generic support for partitioning of MTD devices"); --- linux-source-2.6.22-2.6.22.orig/drivers/mtd/Makefile +++ linux-source-2.6.22-2.6.22/drivers/mtd/Makefile @@ -3,9 +3,9 @@ # # Core functionality. +obj-$(CONFIG_MTD) += mtd.o mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o -obj-$(CONFIG_MTD) += $(mtd-y) obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o --- linux-source-2.6.22-2.6.22.orig/drivers/mtd/mtdsuper.c +++ linux-source-2.6.22-2.6.22/drivers/mtd/mtdsuper.c @@ -70,6 +70,8 @@ DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n", mtd->index, mtd->name); + sb->s_flags = flags; + ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (ret < 0) { up_write(&sb->s_umount); @@ -230,3 +232,5 @@ } EXPORT_SYMBOL_GPL(kill_mtd_super); + +MODULE_LICENSE("GPL"); --- linux-source-2.6.22-2.6.22.orig/drivers/bluetooth/bcm203x.c +++ linux-source-2.6.22-2.6.22/drivers/bluetooth/bcm203x.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -42,7 +43,7 @@ #define BT_DBG(D...) #endif -#define VERSION "1.1" +#define VERSION "1.0" static int ignore = 0; @@ -71,7 +72,7 @@ unsigned long state; - struct work_struct work; + struct timer_list timer; struct urb *urb; unsigned char *buffer; @@ -104,7 +105,7 @@ data->state = BCM203X_SELECT_MEMORY; - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + (HZ / 10)); break; case BCM203X_SELECT_MEMORY: @@ -157,10 +158,9 @@ } } -static void bcm203x_work(struct work_struct *work) +static void bcm203x_timer(unsigned long user_data) { - struct bcm203x_data *data = - container_of(work, struct bcm203x_data, work); + struct bcm203x_data *data = (struct bcm203x_data *) user_data; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); @@ -247,11 +247,13 @@ release_firmware(firmware); - INIT_WORK(&data->work, bcm203x_work); + init_timer(&data->timer); + data->timer.function = bcm203x_timer; + data->timer.data = (unsigned long) data; usb_set_intfdata(intf, data); - schedule_work(&data->work); + mod_timer(&data->timer, jiffies + HZ); return 0; } --- linux-source-2.6.22-2.6.22.orig/drivers/misc/sony-laptop.c +++ linux-source-2.6.22-2.6.22/drivers/misc/sony-laptop.c @@ -732,6 +732,12 @@ break; } } + + /* set the last requested brightness level */ + if (sony_backlight_device && + !sony_backlight_update_status(sony_backlight_device)) + printk(KERN_WARNING DRV_PFX "unable to restore brightness level"); + return 0; } @@ -908,7 +914,9 @@ #define SONYPI_DEVICE_TYPE2 0x00000002 #define SONYPI_DEVICE_TYPE3 0x00000004 -#define SONY_PIC_EV_MASK 0xff +#define SONYPI_TYPE1_OFFSET 0x04 +#define SONYPI_TYPE2_OFFSET 0x12 +#define SONYPI_TYPE3_OFFSET 0x12 struct sony_pic_ioport { struct acpi_resource_io io; @@ -922,6 +930,7 @@ struct sony_pic_dev { int model; + u16 evport_offset; u8 camera_power; u8 bluetooth_power; u8 wwan_power; @@ -1998,20 +2007,17 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) { int i, j; - u32 port_val = 0; u8 ev = 0; u8 data_mask = 0; u8 device_event = 0; struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; - acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val, - dev->cur_ioport->io.address_length); - ev = port_val & SONY_PIC_EV_MASK; - data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8)); + ev = inb_p(dev->cur_ioport->io.minimum); + data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); - dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n", - port_val, ev, data_mask, dev->cur_ioport->io.minimum); + dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", + ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; @@ -2102,6 +2108,20 @@ spic_dev.model = sony_pic_detect_device_type(); mutex_init(&spic_dev.lock); + /* model specific characteristics */ + switch(spic_dev.model) { + case SONYPI_DEVICE_TYPE1: + spic_dev.evport_offset = SONYPI_TYPE1_OFFSET; + break; + case SONYPI_DEVICE_TYPE3: + spic_dev.evport_offset = SONYPI_TYPE3_OFFSET; + break; + case SONYPI_DEVICE_TYPE2: + default: + spic_dev.evport_offset = SONYPI_TYPE2_OFFSET; + break; + } + /* read _PRS resources */ result = sony_pic_possible_resources(device); if (result) { --- linux-source-2.6.22-2.6.22.orig/drivers/misc/thinkpad_acpi.c +++ linux-source-2.6.22-2.6.22/drivers/misc/thinkpad_acpi.c @@ -2040,7 +2040,8 @@ static int __init cmos_init(struct ibm_init_struct *iibm) { int res; - + struct acpi_namespace_node *node; + vdbg_printk(TPACPI_DBG_INIT, "initializing cmos commands subdriver\n"); @@ -2053,6 +2054,11 @@ if (res) return res; + node = cmos_handle; + + if (node) + acpi_method_notify_enable (node->name.ascii); + return (cmos_handle)? 0 : 1; } @@ -2678,12 +2684,43 @@ .update_status = brightness_update_status, }; +static acpi_status find_acpi_video(acpi_handle handle, u32 lvl, void *context, void ** rx) +{ + int BCM; + int BCL; + int BQC; + acpi_handle h_dummy1; + int *acpi_video = context; + + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy1))) + BCM = 1; + + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy1))) + BCL = 1; + + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BQC", &h_dummy1))) + BQC = 1; + + if (BQC && BCL && BCM) + *acpi_video = 1; + + return AE_OK; +} + static int __init brightness_init(struct ibm_init_struct *iibm) { int b; + int acpi_video = 0; vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); - + + acpi_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_acpi_video, &acpi_video, + NULL); + + if (acpi_video) + return 0; + b = brightness_get(NULL); if (b < 0) return b; --- linux-source-2.6.22-2.6.22.orig/drivers/video/vesafb.c +++ linux-source-2.6.22-2.6.22/drivers/video/vesafb.c @@ -28,6 +28,12 @@ #define dac_reg (0x3c8) #define dac_val (0x3c9) +struct vesafb_info +{ + u32 pseudo_palette[256]; + int mtrr_hdl; +}; + /* --------------------------------------------------------------------- */ static struct fb_var_screeninfo vesafb_defined __initdata = { @@ -47,16 +53,37 @@ .accel = FB_ACCEL_NONE, }; +#ifndef MODULE static int inverse __read_mostly; +#endif static int mtrr __read_mostly; /* disable mtrr */ static int vram_remap __initdata; /* Set amount of memory to be used */ static int vram_total __initdata; /* Set total amount of memory */ static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ +static int redraw __read_mostly; static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ +static int ywrap __read_mostly; static void (*pmi_start)(void) __read_mostly; static void (*pmi_pal) (void) __read_mostly; static int depth __read_mostly; static int vga_compat __read_mostly; + +module_param(redraw, bool, 0); +module_param(ypan, bool, 0); +module_param(ywrap, bool, 0); +module_param_named(vgapal, pmi_setpal, invbool, 0); +MODULE_PARM_DESC(vgapal, "Use VGA for setting palette (default)"); +module_param_named(pmipal, pmi_setpal, bool, 0); +MODULE_PARM_DESC(pmipal, "Use PMI for setting palette"); +module_param(mtrr, bool, 0); +MODULE_PARM_DESC(mtrr, "Enable MTRR support (default)"); +module_param_named(nomtrr, mtrr, invbool, 0); +MODULE_PARM_DESC(nomtrr, "Disable MTRR support"); +module_param(vram_remap, int, 0); +MODULE_PARM_DESC(vram_remap, "Set total amount of memory to be used"); +module_param(vram_total, int, 0); +MODULE_PARM_DESC(vram_total, "Total amount of memory"); + /* --------------------------------------------------------------------- */ static int vesafb_pan_display(struct fb_var_screeninfo *var, @@ -183,6 +210,7 @@ .fb_imageblit = cfb_imageblit, }; +#ifndef MODULE static int __init vesafb_setup(char *options) { char *this_opt; @@ -216,6 +244,7 @@ } return 0; } +#endif static int __init vesafb_probe(struct platform_device *dev) { @@ -463,8 +492,28 @@ return err; } +static int __exit vesafb_remove(struct platform_device *device) +{ + struct fb_info *info = dev_get_drvdata(&device->dev); + + unregister_framebuffer(info); +#ifdef CONFIG_MTRR + { + struct vesafb_info *vfb_info = (struct vesafb_info *) info->par; + if (vfb_info->mtrr_hdl >= 0) + mtrr_del(vfb_info->mtrr_hdl, 0, 0); + } +#endif + iounmap(info->screen_base); + framebuffer_release(info); + release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len); + + return 0; +} + static struct platform_driver vesafb_driver = { .probe = vesafb_probe, + .remove = vesafb_remove, .driver = { .name = "vesafb", }, @@ -475,11 +524,18 @@ static int __init vesafb_init(void) { int ret; +#ifndef MODULE char *option = NULL; /* ignore error return of fb_get_options */ fb_get_options("vesafb", &option); vesafb_setup(option); +#else + if (redraw) + ypan = 0; + if (ywrap) + ypan = 2; +#endif ret = platform_driver_register(&vesafb_driver); if (!ret) { @@ -498,6 +554,14 @@ return ret; } + +static void __exit vesafb_exit(void) +{ + platform_device_unregister(vesafb_device); + platform_driver_unregister(&vesafb_driver); +} + module_init(vesafb_init); +module_exit(vesafb_exit); MODULE_LICENSE("GPL"); --- linux-source-2.6.22-2.6.22.orig/drivers/video/igafb.c +++ linux-source-2.6.22-2.6.22/drivers/video/igafb.c @@ -379,10 +379,6 @@ if (fb_get_options("igafb", NULL)) return -ENODEV; - /* Do not attach when we have a serial console. */ - if (!con_is_present()) - return -ENXIO; - pdev = pci_get_device(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, 0); if (pdev == NULL) { --- linux-source-2.6.22-2.6.22.orig/drivers/video/macmodes.c +++ linux-source-2.6.22-2.6.22/drivers/video/macmodes.c @@ -369,9 +369,8 @@ * */ -int __devinit mac_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - unsigned int default_bpp) +int mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, + const char *mode_option, unsigned int default_bpp) { const struct fb_videomode *db = NULL; unsigned int dbsize = 0; --- linux-source-2.6.22-2.6.22.orig/drivers/video/stifb.c +++ linux-source-2.6.22-2.6.22/drivers/video/stifb.c @@ -1100,13 +1100,18 @@ /* only supported cards are allowed */ switch (fb->id) { case CRT_ID_VISUALIZE_EG: - /* look for a double buffering device like e.g. the - "INTERNAL_EG_DX1024" in the RDI precisionbook laptop - which won't work. The same device in non-double - buffering mode returns "INTERNAL_EG_X1024". */ - if (strstr(sti->outptr.dev_name, "EG_DX")) { - printk(KERN_WARNING - "stifb: ignoring '%s'. Disable double buffering in IPL menu.\n", + /* Visualize cards can run either in "double buffer" or + "standard" mode. Depending on the mode, the card reports + a different device name, e.g. "INTERNAL_EG_DX1024" in double + buffer mode and "INTERNAL_EG_X1024" in standard mode. + Since this driver only supports standard mode, we check + if the device name contains the string "DX" and tell the + user how to reconfigure the card. */ + if (strstr(sti->outptr.dev_name, "DX")) { + printk(KERN_WARNING "WARNING: stifb framebuffer driver does not " + "support '%s' in double-buffer mode.\n" + KERN_WARNING "WARNING: Please disable the double-buffer mode " + "in IPL menu (the PARISC-BIOS).\n", sti->outptr.dev_name); goto out_err0; } --- linux-source-2.6.22-2.6.22.orig/drivers/video/console/sticore.c +++ linux-source-2.6.22-2.6.22/drivers/video/console/sticore.c @@ -232,18 +232,14 @@ } -/* FIXME: Do we have another solution for this ? */ -static void sti_flush(unsigned long from, unsigned long len) +static void sti_flush(unsigned long start, unsigned long end) { - flush_data_cache(); - flush_kernel_dcache_range(from, len); - flush_icache_range(from, from+len); + flush_icache_range(start, end); } void __devinit sti_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; /* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */ @@ -260,7 +256,7 @@ dest++; } - sti_flush(dest_start, dest_len); + sti_flush(dest_start, (unsigned long)dest); } @@ -663,7 +659,6 @@ static void __devinit sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; while (count) { @@ -672,7 +667,8 @@ base += 4; dest++; } - sti_flush(dest_start, dest_len); + + sti_flush(dest_start, (unsigned long)dest); } static struct sti_rom * __devinit --- linux-source-2.6.22-2.6.22.orig/drivers/video/console/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/video/console/Kconfig @@ -129,7 +129,7 @@ oriented. config STI_CONSOLE - tristate "STI text console" + bool "STI text console" depends on PARISC default y help --- linux-source-2.6.22-2.6.22.orig/drivers/video/Kconfig +++ linux-source-2.6.22-2.6.22/drivers/video/Kconfig @@ -586,8 +586,8 @@ Say Y if you have one of those. config FB_VESA - bool "VESA VGA graphics support" - depends on (FB = y) && X86 + tristate "VESA VGA graphics support" + depends on FB && X86 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT --- linux-source-2.6.22-2.6.22.orig/drivers/video/backlight/cr_bllcd.c +++ linux-source-2.6.22-2.6.22/drivers/video/backlight/cr_bllcd.c @@ -174,7 +174,7 @@ struct cr_panel *crp; u8 dev_en; - crp = kzalloc(sizeof(crp), GFP_KERNEL); + crp = kzalloc(sizeof(*crp), GFP_KERNEL); if (crp == NULL) return -ENOMEM; --- linux-source-2.6.22-2.6.22.orig/drivers/video/macmodes.h +++ linux-source-2.6.22-2.6.22/drivers/video/macmodes.h @@ -55,10 +55,10 @@ extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, int *cmode); extern int mac_map_monitor_sense(int sense); -extern int __devinit mac_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, - const char *mode_option, - unsigned int default_bpp); +extern int mac_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, + const char *mode_option, + unsigned int default_bpp); /* --- linux-source-2.6.22-2.6.22.orig/drivers/video/aty/atyfb_base.c +++ linux-source-2.6.22-2.6.22/drivers/video/aty/atyfb_base.c @@ -2913,10 +2913,6 @@ int node, len, i, j, ret; u32 mem, chip_id; - /* Do not attach when we have a serial console. */ - if (!con_is_present()) - return -ENXIO; - /* * Map memory-mapped registers. */ --- linux-source-2.6.22-2.6.22.orig/net/bridge/br_if.c +++ linux-source-2.6.22-2.6.22/net/bridge/br_if.c @@ -360,35 +360,15 @@ void br_features_recompute(struct net_bridge *br) { struct net_bridge_port *p; - unsigned long features, checksum; + unsigned long features; - checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; - features = br->feature_mask & ~NETIF_F_ALL_CSUM; + features = br->feature_mask; list_for_each_entry(p, &br->port_list, list) { - unsigned long feature = p->dev->features; - - if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) - checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; - if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) - checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; - if (!(feature & NETIF_F_IP_CSUM)) - checksum = 0; - - if (feature & NETIF_F_GSO) - feature |= NETIF_F_GSO_SOFTWARE; - feature |= NETIF_F_GSO; - - features &= feature; + features = netdev_compute_features(features, p->dev->features); } - if (!(checksum & NETIF_F_ALL_CSUM)) - features &= ~NETIF_F_SG; - if (!(features & NETIF_F_SG)) - features &= ~NETIF_F_GSO_MASK; - - br->dev->features = features | checksum | NETIF_F_LLTX | - NETIF_F_GSO_ROBUST; + br->dev->features = features; } /* called with RTNL */ --- linux-source-2.6.22-2.6.22.orig/net/bridge/br_device.c +++ linux-source-2.6.22-2.6.22/net/bridge/br_device.c @@ -179,5 +179,6 @@ dev->priv_flags = IFF_EBRIDGE; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | - NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; + NETIF_F_GSO_SOFTWARE | NETIF_F_NO_CSUM | + NETIF_F_GSO_ROBUST | NETIF_F_LLTX; } --- linux-source-2.6.22-2.6.22.orig/net/bridge/netfilter/ebt_ulog.c +++ linux-source-2.6.22-2.6.22/net/bridge/netfilter/ebt_ulog.c @@ -308,12 +308,8 @@ else if ((ret = ebt_register_watcher(&ulog))) sock_release(ebtulognl->sk_socket); - if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) { - printk(KERN_WARNING "ebt_ulog: not logging via ulog " - "since somebody else already registered for PF_BRIDGE\n"); - /* we cannot make module load fail here, since otherwise - * ebtables userspace would abort */ - } + if (ret == 0) + nf_log_register(PF_BRIDGE, &ebt_ulog_logger); return ret; } --- linux-source-2.6.22-2.6.22.orig/net/bridge/netfilter/ebt_log.c +++ linux-source-2.6.22-2.6.22/net/bridge/netfilter/ebt_log.c @@ -196,10 +196,8 @@ ret = ebt_register_watcher(&log); if (ret < 0) return ret; - ret = nf_log_register(PF_BRIDGE, &ebt_log_logger); - if (ret < 0 && ret != -EEXIST) - ebt_unregister_watcher(&log); - return ret; + nf_log_register(PF_BRIDGE, &ebt_log_logger); + return 0; } static void __exit ebt_log_fini(void) --- linux-source-2.6.22-2.6.22.orig/net/bridge/br_netfilter.c +++ linux-source-2.6.22-2.6.22/net/bridge/br_netfilter.c @@ -509,8 +509,14 @@ int (*okfn)(struct sk_buff *)) { struct iphdr *iph; - __u32 len; struct sk_buff *skb = *pskb; + __u32 len = nf_bridge_encap_header_len(skb); + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + return NF_STOLEN; + + if (unlikely(!pskb_may_pull(skb, len))) + goto out; if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) { @@ -518,8 +524,6 @@ if (!brnf_call_ip6tables) return NF_ACCEPT; #endif - if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) - goto out; nf_bridge_pull_encap_header_rcsum(skb); return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); } @@ -532,8 +536,6 @@ !IS_PPPOE_IP(skb)) return NF_ACCEPT; - if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) - goto out; nf_bridge_pull_encap_header_rcsum(skb); if (!pskb_may_pull(skb, sizeof(struct iphdr))) --- linux-source-2.6.22-2.6.22.orig/net/unix/af_unix.c +++ linux-source-2.6.22-2.6.22/net/unix/af_unix.c @@ -807,7 +807,7 @@ */ mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); - err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, mode, 0); if (err) goto out_mknod_dput; mutex_unlock(&nd.dentry->d_inode->i_mutex); --- linux-source-2.6.22-2.6.22.orig/net/sched/sch_api.c +++ linux-source-2.6.22-2.6.22/net/sched/sch_api.c @@ -290,11 +290,7 @@ wd->qdisc->flags &= ~TCQ_F_THROTTLED; smp_wmb(); - if (spin_trylock(&dev->queue_lock)) { - qdisc_run(dev); - spin_unlock(&dev->queue_lock); - } else - netif_schedule(dev); + netif_schedule(dev); return HRTIMER_NORESTART; } --- linux-source-2.6.22-2.6.22.orig/net/dccp/ccids/ccid2.c +++ linux-source-2.6.22-2.6.22/net/dccp/ccids/ccid2.c @@ -298,7 +298,7 @@ int rc; ccid2_pr_debug("allocating more space in history\n"); - rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); + rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any()); BUG_ON(rc); /* XXX what do we do? */ next = hctx->ccid2hctx_seqh->ccid2s_next; --- linux-source-2.6.22-2.6.22.orig/net/dccp/feat.c +++ linux-source-2.6.22-2.6.22/net/dccp/feat.c @@ -30,7 +30,7 @@ } if (!dccp_feat_is_valid_length(type, feature, len)) { DCCP_WARN("invalid length %d\n", len); - return 1; + return -EINVAL; } /* XXX add further sanity checks */ --- linux-source-2.6.22-2.6.22.orig/net/8021q/vlan_dev.c +++ linux-source-2.6.22-2.6.22/net/8021q/vlan_dev.c @@ -116,12 +116,22 @@ struct packet_type* ptype, struct net_device *orig_dev) { unsigned char *rawp = NULL; - struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data); + struct vlan_hdr *vhdr; unsigned short vid; struct net_device_stats *stats; unsigned short vlan_TCI; __be16 proto; + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + return -1; + + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) { + kfree_skb(skb); + return -1; + } + + vhdr = (struct vlan_hdr *)(skb->data); + /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */ vlan_TCI = ntohs(vhdr->h_vlan_TCI); --- linux-source-2.6.22-2.6.22.orig/net/core/gen_estimator.c +++ linux-source-2.6.22-2.6.22/net/core/gen_estimator.c @@ -79,27 +79,27 @@ struct gen_estimator { - struct gen_estimator *next; + struct list_head list; struct gnet_stats_basic *bstats; struct gnet_stats_rate_est *rate_est; spinlock_t *stats_lock; - unsigned interval; int ewma_log; u64 last_bytes; u32 last_packets; u32 avpps; u32 avbps; + struct rcu_head e_rcu; }; struct gen_estimator_head { struct timer_list timer; - struct gen_estimator *list; + struct list_head list; }; static struct gen_estimator_head elist[EST_MAX_INTERVAL+1]; -/* Estimator array lock */ +/* Protects against NULL dereference */ static DEFINE_RWLOCK(est_lock); static void est_timer(unsigned long arg) @@ -107,13 +107,17 @@ int idx = (int)arg; struct gen_estimator *e; - read_lock(&est_lock); - for (e = elist[idx].list; e; e = e->next) { + rcu_read_lock(); + list_for_each_entry_rcu(e, &elist[idx].list, list) { u64 nbytes; u32 npackets; u32 rate; spin_lock(e->stats_lock); + read_lock(&est_lock); + if (e->bstats == NULL) + goto skip; + nbytes = e->bstats->bytes; npackets = e->bstats->packets; rate = (nbytes - e->last_bytes)<<(7 - idx); @@ -125,11 +129,14 @@ e->last_packets = npackets; e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log; e->rate_est->pps = (e->avpps+0x1FF)>>10; +skip: + read_unlock(&est_lock); spin_unlock(e->stats_lock); } - mod_timer(&elist[idx].timer, jiffies + ((HZ<interval = parm->interval + 2; + idx = parm->interval + 2; est->bstats = bstats; est->rate_est = rate_est; est->stats_lock = stats_lock; @@ -173,20 +185,25 @@ est->last_packets = bstats->packets; est->avpps = rate_est->pps<<10; - est->next = elist[est->interval].list; - if (est->next == NULL) { - init_timer(&elist[est->interval].timer); - elist[est->interval].timer.data = est->interval; - elist[est->interval].timer.expires = jiffies + ((HZ<interval)/4); - elist[est->interval].timer.function = est_timer; - add_timer(&elist[est->interval].timer); + if (!elist[idx].timer.function) { + INIT_LIST_HEAD(&elist[idx].list); + setup_timer(&elist[idx].timer, est_timer, idx); } - write_lock_bh(&est_lock); - elist[est->interval].list = est; - write_unlock_bh(&est_lock); + + if (list_empty(&elist[idx].list)) + mod_timer(&elist[idx].timer, jiffies + ((HZ<list, &elist[idx].list); return 0; } +static void __gen_kill_estimator(struct rcu_head *head) +{ + struct gen_estimator *e = container_of(head, + struct gen_estimator, e_rcu); + kfree(e); +} + /** * gen_kill_estimator - remove a rate estimator * @bstats: basic statistics @@ -194,31 +211,32 @@ * * Removes the rate estimator specified by &bstats and &rate_est * and deletes the timer. + * + * NOTE: Called under rtnl_mutex */ void gen_kill_estimator(struct gnet_stats_basic *bstats, struct gnet_stats_rate_est *rate_est) { int idx; - struct gen_estimator *est, **pest; + struct gen_estimator *e, *n; for (idx=0; idx <= EST_MAX_INTERVAL; idx++) { - int killed = 0; - pest = &elist[idx].list; - while ((est=*pest) != NULL) { - if (est->rate_est != rate_est || est->bstats != bstats) { - pest = &est->next; + + /* Skip non initialized indexes */ + if (!elist[idx].timer.function) + continue; + + list_for_each_entry_safe(e, n, &elist[idx].list, list) { + if (e->rate_est != rate_est || e->bstats != bstats) continue; - } write_lock_bh(&est_lock); - *pest = est->next; + e->bstats = NULL; write_unlock_bh(&est_lock); - kfree(est); - killed++; + list_del_rcu(&e->list); + call_rcu(&e->e_rcu, __gen_kill_estimator); } - if (killed && elist[idx].list == NULL) - del_timer(&elist[idx].timer); } } --- linux-source-2.6.22-2.6.22.orig/net/core/netpoll.c +++ linux-source-2.6.22-2.6.22/net/core/netpoll.c @@ -781,7 +781,6 @@ spin_unlock_irqrestore(&npinfo->rx_lock, flags); } - np->dev->npinfo = NULL; if (atomic_dec_and_test(&npinfo->refcnt)) { skb_queue_purge(&npinfo->arp_tx); skb_queue_purge(&npinfo->txq); @@ -794,6 +793,7 @@ kfree_skb(skb); } kfree(npinfo); + np->dev->npinfo = NULL; } } --- linux-source-2.6.22-2.6.22.orig/net/core/dev.c +++ linux-source-2.6.22-2.6.22/net/core/dev.c @@ -3635,6 +3635,44 @@ static int __init netdev_dma_register(void) { return -ENODEV; } #endif /* CONFIG_NET_DMA */ +/** + * netdev_compute_feature - compute conjunction of two feature sets + * @all: first feature set + * @one: second feature set + * + * Computes a new feature set after adding a device with feature set + * @one to the master device with current feature set @all. Returns + * the new feature set. + */ +int netdev_compute_features(unsigned long all, unsigned long one) +{ + /* if device needs checksumming, downgrade to hw checksumming */ + if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) + all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; + + /* if device can't do all checksum, downgrade to ipv4 */ + if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM)) + all ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; + + if (one & NETIF_F_GSO) + one |= NETIF_F_GSO_SOFTWARE; + one |= NETIF_F_GSO; + + /* If even one device supports robust GSO, enable it for all. */ + if (one & NETIF_F_GSO_ROBUST) + all |= NETIF_F_GSO_ROBUST; + + all &= one | NETIF_F_LLTX; + + if (!(all & NETIF_F_ALL_CSUM)) + all &= ~NETIF_F_SG; + if (!(all & NETIF_F_SG)) + all &= ~NETIF_F_GSO_MASK; + + return all; +} +EXPORT_SYMBOL(netdev_compute_features); + /* * Initialize the DEV module. At boot time this walks the device list and * unhooks any devices that fail to initialise (normally hardware not --- linux-source-2.6.22-2.6.22.orig/net/core/datagram.c +++ linux-source-2.6.22-2.6.22/net/core/datagram.c @@ -450,6 +450,9 @@ __wsum csum; int chunk = skb->len - hlen; + if (!chunk) + return 0; + /* Skip filled elements. * Pretty silly, look at memcpy_toiovec, though 8) */ --- linux-source-2.6.22-2.6.22.orig/net/core/pktgen.c +++ linux-source-2.6.22-2.6.22/net/core/pktgen.c @@ -111,6 +111,9 @@ * * 802.1Q/Q-in-Q support by Francesco Fondelli (FF) * + * Fixed src_mac command to set source mac of packet to value specified in + * command by Adit Ranadive + * */ #include #include @@ -1415,8 +1418,11 @@ } if (!strcmp(name, "src_mac")) { char *v = valstr; + unsigned char old_smac[ETH_ALEN]; unsigned char *m = pkt_dev->src_mac; + memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); + len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) { return len; @@ -1445,6 +1451,10 @@ } } + /* Set up Src MAC */ + if (compare_ether_addr(old_smac, pkt_dev->src_mac)) + memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN); + sprintf(pg_result, "OK: srcmac"); return count; } --- linux-source-2.6.22-2.6.22.orig/net/ipv6/addrconf.c +++ linux-source-2.6.22-2.6.22/net/ipv6/addrconf.c @@ -1021,7 +1021,7 @@ hiscore.rule++; } if (ipv6_saddr_preferred(score.addr_type) || - (((ifa_result->flags & + (((ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) { score.attrs |= IPV6_SADDR_SCORE_PREFERRED; if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { @@ -2472,6 +2472,7 @@ write_unlock_bh(&idev->lock); __ipv6_ifa_notify(RTM_DELADDR, ifa); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); in6_ifa_put(ifa); write_lock_bh(&idev->lock); --- linux-source-2.6.22-2.6.22.orig/net/ipv6/ip6_output.c +++ linux-source-2.6.22-2.6.22/net/ipv6/ip6_output.c @@ -790,7 +790,7 @@ /* * Copy a block of the IP datagram. */ - if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len)) + if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len)) BUG(); left -= len; @@ -1423,8 +1423,9 @@ struct sk_buff *skb; while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { - IP6_INC_STATS(ip6_dst_idev(skb->dst), - IPSTATS_MIB_OUTDISCARDS); + if (skb->dst) + IP6_INC_STATS(ip6_dst_idev(skb->dst), + IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); } --- linux-source-2.6.22-2.6.22.orig/net/ipv6/ndisc.c +++ linux-source-2.6.22-2.6.22/net/ipv6/ndisc.c @@ -736,7 +736,7 @@ * so fail our DAD process */ addrconf_dad_failure(ifp); - goto out; + return; } else { /* * This is not a dad solicitation. --- linux-source-2.6.22-2.6.22.orig/net/ipv6/tcp_ipv6.c +++ linux-source-2.6.22-2.6.22/net/ipv6/tcp_ipv6.c @@ -644,6 +644,7 @@ if (tp->md5sig_info->entries6 == 0) { kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; + tp->md5sig_info->alloced6 = 0; tcp_free_md5sig_pool(); @@ -2134,7 +2135,6 @@ .shutdown = tcp_shutdown, .setsockopt = tcp_setsockopt, .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, .recvmsg = tcp_recvmsg, .backlog_rcv = tcp_v6_do_rcv, .hash = tcp_v6_hash, --- linux-source-2.6.22-2.6.22.orig/net/ipv6/icmp.c +++ linux-source-2.6.22-2.6.22/net/ipv6/icmp.c @@ -604,7 +604,7 @@ read_lock(&raw_v6_lock); if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) { - while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, + while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr, IP6CB(skb)->iif))) { rawv6_err(sk, skb, NULL, type, code, inner_offset, info); sk = sk_next(sk); --- linux-source-2.6.22-2.6.22.orig/net/ipv6/af_inet6.c +++ linux-source-2.6.22-2.6.22/net/ipv6/af_inet6.c @@ -487,7 +487,7 @@ .shutdown = inet_shutdown, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */ - .sendmsg = inet_sendmsg, /* ok */ + .sendmsg = tcp_sendmsg, /* ok */ .recvmsg = sock_common_recvmsg, /* ok */ .mmap = sock_no_mmap, .sendpage = tcp_sendpage, --- linux-source-2.6.22-2.6.22.orig/net/ipv6/ipv6_sockglue.c +++ linux-source-2.6.22-2.6.22/net/ipv6/ipv6_sockglue.c @@ -825,7 +825,7 @@ return 0; len = min_t(unsigned int, len, ipv6_optlen(hdr)); - if (copy_to_user(optval, hdr, len)); + if (copy_to_user(optval, hdr, len)) return -EFAULT; return ipv6_optlen(hdr); } --- linux-source-2.6.22-2.6.22.orig/net/ipv6/anycast.c +++ linux-source-2.6.22-2.6.22/net/ipv6/anycast.c @@ -66,6 +66,7 @@ break; } read_unlock_bh(&idev->lock); + in6_dev_put(idev); } rcu_read_unlock(); return onlink; --- linux-source-2.6.22-2.6.22.orig/net/ipv6/sit.c +++ linux-source-2.6.22-2.6.22/net/ipv6/sit.c @@ -395,9 +395,9 @@ } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); - kfree_skb(skb); read_unlock(&ipip6_lock); out: + kfree_skb(skb); return 0; } --- linux-source-2.6.22-2.6.22.orig/net/ipv6/netfilter/ip6t_LOG.c +++ linux-source-2.6.22-2.6.22/net/ipv6/netfilter/ip6t_LOG.c @@ -490,10 +490,8 @@ ret = xt_register_target(&ip6t_log_reg); if (ret < 0) return ret; - ret = nf_log_register(PF_INET6, &ip6t_logger); - if (ret < 0 && ret != -EEXIST) - xt_unregister_target(&ip6t_log_reg); - return ret; + nf_log_register(PF_INET6, &ip6t_logger); + return 0; } static void __exit ip6t_log_fini(void) --- linux-source-2.6.22-2.6.22.orig/net/ipv6/ip6_tunnel.c +++ linux-source-2.6.22-2.6.22/net/ipv6/ip6_tunnel.c @@ -962,8 +962,8 @@ dsfield = ipv4_get_dsfield(iph); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) - fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT) - & IPV6_TCLASS_MASK); + fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) + & IPV6_TCLASS_MASK; err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); if (err != 0) { --- linux-source-2.6.22-2.6.22.orig/net/ipv6/raw.c +++ linux-source-2.6.22-2.6.22/net/ipv6/raw.c @@ -858,11 +858,10 @@ ip6_flush_pending_frames(sk); else if (!(msg->msg_flags & MSG_MORE)) err = rawv6_push_pending_frames(sk, &fl, rp); + release_sock(sk); } done: dst_release(dst); - if (!inet->hdrincl) - release_sock(sk); out: fl6_sock_release(flowlabel); return err<0?err:len; --- linux-source-2.6.22-2.6.22.orig/net/sunrpc/svcsock.c +++ linux-source-2.6.22-2.6.22/net/sunrpc/svcsock.c @@ -1090,7 +1090,8 @@ serv->sv_name); printk(KERN_NOTICE "%s: last TCP connect from %s\n", - serv->sv_name, buf); + serv->sv_name, __svc_print_addr(sin, + buf, sizeof(buf))); } /* * Always select the oldest socket. It's not fair, @@ -1572,7 +1573,8 @@ if (!test_and_set_bit(SK_OLD, &svsk->sk_flags)) continue; - if (atomic_read(&svsk->sk_inuse) || test_bit(SK_BUSY, &svsk->sk_flags)) + if (atomic_read(&svsk->sk_inuse) > 1 + || test_bit(SK_BUSY, &svsk->sk_flags)) continue; atomic_inc(&svsk->sk_inuse); list_move(le, &to_be_aged); --- linux-source-2.6.22-2.6.22.orig/net/sunrpc/auth_gss/svcauth_gss.c +++ linux-source-2.6.22-2.6.22/net/sunrpc/auth_gss/svcauth_gss.c @@ -760,11 +760,12 @@ new->h.flavour = &svcauthops_gss; new->pseudoflavor = pseudoflavor; + stat = 0; test = auth_domain_lookup(name, &new->h); - if (test != &new->h) { /* XXX Duplicate registration? */ - auth_domain_put(&new->h); - /* dangling ref-count... */ - goto out; + if (test != &new->h) { /* Duplicate registration */ + auth_domain_put(test); + kfree(new->h.name); + goto out_free_dom; } return 0; --- linux-source-2.6.22-2.6.22.orig/net/802/psnap.c +++ linux-source-2.6.22-2.6.22/net/802/psnap.c @@ -55,6 +55,9 @@ .type = __constant_htons(ETH_P_SNAP), }; + if (unlikely(!pskb_may_pull(skb, 5))) + goto drop; + rcu_read_lock(); proto = find_snap_client(skb_transport_header(skb)); if (proto) { @@ -62,14 +65,18 @@ skb->transport_header += 5; skb_pull_rcsum(skb, 5); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); - } else { - skb->sk = NULL; - kfree_skb(skb); - rc = 1; } - rcu_read_unlock(); + + if (unlikely(!proto)) + goto drop; + +out: return rc; + +drop: + kfree_skb(skb); + goto out; } /* --- linux-source-2.6.22-2.6.22.orig/net/socket.c +++ linux-source-2.6.22-2.6.22/net/socket.c @@ -1169,7 +1169,7 @@ module_put(pf->owner); err = security_socket_post_create(sock, family, type, protocol, kern); if (err) - goto out_release; + goto out_sock_release; *res = sock; return 0; --- linux-source-2.6.22-2.6.22.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ linux-source-2.6.22-2.6.22/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -271,8 +271,11 @@ */ dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n"); ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); - if (ieee80211softmac_start_scan(mac)) + if (ieee80211softmac_start_scan(mac)) { dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); + mac->associnfo.associating = 0; + mac->associnfo.associated = 0; + } goto out; } else { mac->associnfo.associating = 0; --- linux-source-2.6.22-2.6.22.orig/net/ieee80211/softmac/ieee80211softmac_wx.c +++ linux-source-2.6.22-2.6.22/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -74,8 +74,8 @@ struct ieee80211softmac_auth_queue_item *authptr; int length = 0; +check_assoc_again: mutex_lock(&sm->associnfo.mutex); - /* Check if we're already associating to this or another network * If it's another network, cancel and start over with our new network * If it's our network, ignore the change, we're already doing it! @@ -88,6 +88,13 @@ !memcmp(n->essid.data, extra, n->essid.len)) { dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", MAC_ARG(sm->associnfo.bssid)); + /* wpa_supplicant expects an association event, regardless of prior + * association state. If associating, then the associnfo.work task + * will send the appropriate event. + */ + if (sm->associnfo.associated) + ieee80211softmac_call_events_locked(sm, + IEEE80211SOFTMAC_EVENT_ASSOCIATED, n); goto out; } else { dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); @@ -98,13 +105,18 @@ cancel_delayed_work(&authptr->work); sm->associnfo.bssvalid = 0; sm->associnfo.bssfixed = 0; - flush_scheduled_work(); sm->associnfo.associating = 0; sm->associnfo.associated = 0; + /* We must unlock to avoid deadlocks with the assoc workqueue + * on the associnfo.mutex */ + mutex_unlock(&sm->associnfo.mutex); + flush_scheduled_work(); + /* Avoid race! Check assoc status again. Maybe someone started an + * association while we flushed. */ + goto check_assoc_again; } } - sm->associnfo.static_essid = 0; sm->associnfo.assoc_wait = 0; --- linux-source-2.6.22-2.6.22.orig/net/ieee80211/ieee80211_rx.c +++ linux-source-2.6.22-2.6.22/net/ieee80211/ieee80211_rx.c @@ -366,6 +366,12 @@ frag = WLAN_GET_SEQ_FRAG(sc); hdrlen = ieee80211_get_hdrlen(fc); + if (skb->len < hdrlen) { + printk(KERN_INFO "%s: invalid SKB length %d\n", + dev->name, skb->len); + goto rx_dropped; + } + /* Put this code here so that we avoid duplicating it in all * Rx paths. - Jean II */ #ifdef CONFIG_WIRELESS_EXT --- linux-source-2.6.22-2.6.22.orig/net/sctp/ipv6.c +++ linux-source-2.6.22-2.6.22/net/sctp/ipv6.c @@ -875,6 +875,10 @@ dev = dev_get_by_index(addr->v6.sin6_scope_id); if (!dev) return 0; + if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { + dev_put(dev); + return 0; + } dev_put(dev); } af = opt->pf->af; --- linux-source-2.6.22-2.6.22.orig/net/sctp/socket.c +++ linux-source-2.6.22-2.6.22/net/sctp/socket.c @@ -4213,7 +4213,9 @@ if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; - if (getaddrs.addr_num <= 0) return -EINVAL; + if (getaddrs.addr_num <= 0 || + getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) + return -EINVAL; /* * For UDP-style sockets, id specifies the association to query. * If the id field is set to the value '0' then the locally bound --- linux-source-2.6.22-2.6.22.orig/net/ipv4/tcp.c +++ linux-source-2.6.22-2.6.22/net/ipv4/tcp.c @@ -658,9 +658,10 @@ return tmp; } -int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, +int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size) { + struct sock *sk = sock->sk; struct iovec *iov; struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; --- linux-source-2.6.22-2.6.22.orig/net/ipv4/af_inet.c +++ linux-source-2.6.22-2.6.22/net/ipv4/af_inet.c @@ -831,7 +831,7 @@ .shutdown = inet_shutdown, .setsockopt = sock_common_setsockopt, .getsockopt = sock_common_getsockopt, - .sendmsg = inet_sendmsg, + .sendmsg = tcp_sendmsg, .recvmsg = sock_common_recvmsg, .mmap = sock_no_mmap, .sendpage = tcp_sendpage, --- linux-source-2.6.22-2.6.22.orig/net/ipv4/tcp_ipv4.c +++ linux-source-2.6.22-2.6.22/net/ipv4/tcp_ipv4.c @@ -2434,7 +2434,6 @@ .shutdown = tcp_shutdown, .setsockopt = tcp_setsockopt, .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, .recvmsg = tcp_recvmsg, .backlog_rcv = tcp_v4_do_rcv, .hash = tcp_v4_hash, --- linux-source-2.6.22-2.6.22.orig/net/ipv4/devinet.c +++ linux-source-2.6.22-2.6.22/net/ipv4/devinet.c @@ -1194,7 +1194,7 @@ for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { if (ip_idx < s_ip_idx) - goto cont; + continue; if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, NLM_F_MULTI) <= 0) --- linux-source-2.6.22-2.6.22.orig/net/ipv4/ah4.c +++ linux-source-2.6.22-2.6.22/net/ipv4/ah4.c @@ -46,7 +46,7 @@ memcpy(daddr, optptr+optlen-4, 4); /* Fall through */ default: - memset(optptr+2, 0, optlen-2); + memset(optptr, 0, optlen); } l -= optlen; optptr += optlen; --- linux-source-2.6.22-2.6.22.orig/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ linux-source-2.6.22-2.6.22/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -189,25 +189,13 @@ h = nf_conntrack_find_get(&innertuple, NULL); if (!h) { - /* Locally generated ICMPs will match inverted if they - haven't been SNAT'ed yet */ - /* FIXME: NAT code has to handle half-done double NAT --RR */ - if (hooknum == NF_IP_LOCAL_OUT) - h = nf_conntrack_find_get(&origtuple, NULL); - - if (!h) { - DEBUGP("icmp_error_message: no match\n"); - return -NF_ACCEPT; - } - - /* Reverse direction from that found */ - if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) - *ctinfo += IP_CT_IS_REPLY; - } else { - if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) - *ctinfo += IP_CT_IS_REPLY; + DEBUGP("icmp_error_message: no match\n"); + return -NF_ACCEPT; } + if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) + *ctinfo += IP_CT_IS_REPLY; + /* Update skb to refer to this connection */ skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; skb->nfctinfo = *ctinfo; --- linux-source-2.6.22-2.6.22.orig/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ linux-source-2.6.22-2.6.22/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -231,6 +231,11 @@ } } } + + /* don't trust len bigger than ctx buffer */ + if (*len > ctx->end - ctx->pointer) + return 0; + return 1; } @@ -249,6 +254,10 @@ if (!asn1_length_decode(ctx, &def, &len)) return 0; + /* primitive shall be definite, indefinite shall be constructed */ + if (*con == ASN1_PRI && !def) + return 0; + if (def) *eoc = ctx->pointer + len; else @@ -429,10 +438,15 @@ unsigned int *len) { unsigned long subid; - unsigned int size; unsigned long *optr; + size_t size; size = eoc - ctx->pointer + 1; + + /* first subid actually encodes first two subids */ + if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) + return 0; + *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) { if (net_ratelimit()) --- linux-source-2.6.22-2.6.22.orig/net/ipv4/netfilter/ipt_LOG.c +++ linux-source-2.6.22-2.6.22/net/ipv4/netfilter/ipt_LOG.c @@ -477,10 +477,8 @@ ret = xt_register_target(&ipt_log_reg); if (ret < 0) return ret; - ret = nf_log_register(PF_INET, &ipt_log_logger); - if (ret < 0 && ret != -EEXIST) - xt_unregister_target(&ipt_log_reg); - return ret; + nf_log_register(PF_INET, &ipt_log_logger); + return 0; } static void __exit ipt_log_fini(void) --- linux-source-2.6.22-2.6.22.orig/net/ipv4/tcp_input.c +++ linux-source-2.6.22-2.6.22/net/ipv4/tcp_input.c @@ -102,11 +102,14 @@ #define FLAG_DATA_LOST 0x80 /* SACK detected data lossage. */ #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ +#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ +#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained DSACK info */ #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) #define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) #define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) +#define FLAG_ANY_PROGRESS (FLAG_FORWARD_PROGRESS|FLAG_SND_UNA_ADVANCED) #define IsReno(tp) ((tp)->rx_opt.sack_ok == 0) #define IsFack(tp) ((tp)->rx_opt.sack_ok & 2) @@ -964,12 +967,14 @@ /* Check for D-SACK. */ if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { + flag |= FLAG_DSACKING_ACK; found_dup_sack = 1; tp->rx_opt.sack_ok |= 4; NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); } else if (num_sacks > 1 && !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { + flag |= FLAG_DSACKING_ACK; found_dup_sack = 1; tp->rx_opt.sack_ok |= 4; NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); @@ -989,6 +994,9 @@ if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window)) return 0; + if (!tp->packets_out) + goto out; + /* SACK fastpath: * if the only SACK change is the increase of the end_seq of * the first block then only apply that SACK block @@ -1257,6 +1265,8 @@ (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0); +out: + #if FASTRETRANS_DEBUG > 0 BUG_TRAP((int)tp->sacked_out >= 0); BUG_TRAP((int)tp->lost_out >= 0); @@ -1398,7 +1408,9 @@ * waiting for the first ACK and did not get it)... */ if ((tp->frto_counter == 1) && !(flag&FLAG_DATA_ACKED)) { - tp->retrans_out += tcp_skb_pcount(skb); + /* For some reason this R-bit might get cleared? */ + if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) + tp->retrans_out += tcp_skb_pcount(skb); /* ...enter this if branch just for the first segment */ flag |= FLAG_DATA_ACKED; } else { @@ -1849,19 +1861,22 @@ } /* Decrease cwnd each second ack. */ -static void tcp_cwnd_down(struct sock *sk) +static void tcp_cwnd_down(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); int decr = tp->snd_cwnd_cnt + 1; - tp->snd_cwnd_cnt = decr&1; - decr >>= 1; + if ((flag&(FLAG_ANY_PROGRESS|FLAG_DSACKING_ACK)) || + (IsReno(tp) && !(flag&FLAG_NOT_DUP))) { + tp->snd_cwnd_cnt = decr&1; + decr >>= 1; - if (decr && tp->snd_cwnd > tcp_cwnd_min(sk)) - tp->snd_cwnd -= decr; + if (decr && tp->snd_cwnd > tcp_cwnd_min(sk)) + tp->snd_cwnd -= decr; - tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); - tp->snd_cwnd_stamp = tcp_time_stamp; + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); + tp->snd_cwnd_stamp = tcp_time_stamp; + } } /* Nothing was retransmitted or returned timestamp is less @@ -2058,7 +2073,7 @@ } tcp_moderate_cwnd(tp); } else { - tcp_cwnd_down(sk); + tcp_cwnd_down(sk, flag); } } @@ -2107,7 +2122,9 @@ { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); - int is_dupack = (tp->snd_una == prior_snd_una && !(flag&FLAG_NOT_DUP)); + int is_dupack = !(flag&(FLAG_SND_UNA_ADVANCED|FLAG_NOT_DUP)); + int do_lost = is_dupack || ((flag&FLAG_DATA_SACKED) && + (tp->fackets_out > tp->reordering)); /* Some technical things: * 1. Reno does not count dupacks (sacked_out) automatically. */ @@ -2191,7 +2208,7 @@ int acked = prior_packets - tp->packets_out; if (IsReno(tp)) tcp_remove_reno_sacks(sk, acked); - is_dupack = tcp_try_undo_partial(sk, acked); + do_lost = tcp_try_undo_partial(sk, acked); } break; case TCP_CA_Loss: @@ -2256,9 +2273,9 @@ tcp_set_ca_state(sk, TCP_CA_Recovery); } - if (is_dupack || tcp_head_timedout(sk)) + if (do_lost || tcp_head_timedout(sk)) tcp_update_scoreboard(sk); - tcp_cwnd_down(sk); + tcp_cwnd_down(sk, flag); tcp_xmit_retransmit_queue(sk); } @@ -2766,6 +2783,9 @@ if (before(ack, prior_snd_una)) goto old_ack; + if (after(ack, prior_snd_una)) + flag |= FLAG_SND_UNA_ADVANCED; + if (sysctl_tcp_abc) { if (icsk->icsk_ca_state < TCP_CA_CWR) tp->bytes_acked += ack - prior_snd_una; --- linux-source-2.6.22-2.6.22.orig/net/ipv4/inet_diag.c +++ linux-source-2.6.22-2.6.22/net/ipv4/inet_diag.c @@ -836,12 +836,16 @@ return inet_diag_get_exact(skb, nlh); } +static DEFINE_MUTEX(inet_diag_mutex); + static void inet_diag_rcv(struct sock *sk, int len) { unsigned int qlen = 0; do { + mutex_lock(&inet_diag_mutex); netlink_run_queue(sk, &qlen, &inet_diag_rcv_msg); + mutex_unlock(&inet_diag_mutex); } while (qlen); } --- linux-source-2.6.22-2.6.22.orig/net/xfrm/xfrm_policy.c +++ linux-source-2.6.22-2.6.22/net/xfrm/xfrm_policy.c @@ -2141,7 +2141,7 @@ if (last == first) break; - last = last->u.next; + last = (struct xfrm_dst *)last->u.dst.next; last->child_mtu_cached = mtu; } --- linux-source-2.6.22-2.6.22.orig/net/netfilter/nf_conntrack_proto_sctp.c +++ linux-source-2.6.22-2.6.22/net/netfilter/nf_conntrack_proto_sctp.c @@ -460,7 +460,8 @@ SCTP_CONNTRACK_NONE, sch->type); /* Invalid: delete conntrack */ - if (newconntrack == SCTP_CONNTRACK_MAX) { + if (newconntrack == SCTP_CONNTRACK_NONE || + newconntrack == SCTP_CONNTRACK_MAX) { DEBUGP("nf_conntrack_sctp: invalid new deleting.\n"); return 0; } --- linux-source-2.6.22-2.6.22.orig/net/rfkill/rfkill-input.c +++ linux-source-2.6.22-2.6.22/net/rfkill/rfkill-input.c @@ -55,7 +55,7 @@ static void rfkill_schedule_toggle(struct rfkill_task *task) { - unsigned int flags; + unsigned long flags; spin_lock_irqsave(&task->lock, flags); --- linux-source-2.6.22-2.6.22.orig/net/bluetooth/rfcomm/tty.c +++ linux-source-2.6.22-2.6.22/net/bluetooth/rfcomm/tty.c @@ -95,6 +95,10 @@ BT_DBG("dev %p dlc %p", dev, dlc); + write_lock_bh(&rfcomm_dev_lock); + list_del_init(&dev->list); + write_unlock_bh(&rfcomm_dev_lock); + rfcomm_dlc_lock(dlc); /* Detach DLC if it's owned by this dev */ if (dlc->owner == dev) @@ -156,8 +160,13 @@ read_lock(&rfcomm_dev_lock); dev = __rfcomm_dev_get(id); - if (dev) - rfcomm_dev_hold(dev); + + if (dev) { + if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) + dev = NULL; + else + rfcomm_dev_hold(dev); + } read_unlock(&rfcomm_dev_lock); @@ -265,6 +274,12 @@ dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); + if (IS_ERR(dev->tty_dev)) { + list_del(&dev->list); + kfree(dev); + return PTR_ERR(dev->tty_dev); + } + return dev->id; } @@ -272,10 +287,7 @@ { BT_DBG("dev %p", dev); - write_lock_bh(&rfcomm_dev_lock); - list_del_init(&dev->list); - write_unlock_bh(&rfcomm_dev_lock); - + set_bit(RFCOMM_TTY_RELEASED, &dev->flags); rfcomm_dev_put(dev); } @@ -329,7 +341,7 @@ if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags); + BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags); if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) return -EPERM; @@ -370,7 +382,7 @@ if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags); + BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags); if (!(dev = rfcomm_dev_get(req.dev_id))) return -ENODEV; @@ -383,6 +395,10 @@ if (req.flags & (1 << RFCOMM_HANGUP_NOW)) rfcomm_dlc_close(dev->dlc, 0); + /* Shut down TTY synchronously before freeing rfcomm_dev */ + if (dev->tty) + tty_vhangup(dev->tty); + rfcomm_dev_del(dev); rfcomm_dev_put(dev); return 0; @@ -415,6 +431,8 @@ list_for_each(p, &rfcomm_dev_list) { struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list); + if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) + continue; (di + n)->id = dev->id; (di + n)->flags = dev->flags; (di + n)->state = dev->dlc->state; --- linux-source-2.6.22-2.6.22.orig/net/bluetooth/hci_core.c +++ linux-source-2.6.22-2.6.22/net/bluetooth/hci_core.c @@ -620,7 +620,8 @@ hdev->flush(hdev); atomic_set(&hdev->cmd_cnt, 1); - hdev->acl_cnt = 0; hdev->sco_cnt = 0; + atomic_set(&hdev->sco_cnt, 0); + hdev->acl_cnt = 0; if (!test_bit(HCI_RAW, &hdev->flags)) ret = __hci_request(hdev, hci_reset_req, 0, @@ -1132,6 +1133,7 @@ { struct hci_dev *hdev = conn->hdev; struct hci_sco_hdr hdr; + ktime_t now; BT_DBG("%s len %d", hdev->name, skb->len); @@ -1140,6 +1142,13 @@ return -EINVAL; } + now = conn->tx_timer.base->get_time(); + + /* force a clean start for 100 ms or later underrun */ + if (conn->tx_timer.expires.tv64 + NSEC_PER_SEC / 10 <= now.tv64) { + conn->tx_timer.expires = now; + } + hdr.handle = cpu_to_le16(conn->handle); hdr.dlen = skb->len; @@ -1157,12 +1166,12 @@ /* ---- HCI TX task (outgoing data) ---- */ -/* HCI Connection scheduler */ -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) +/* HCI ACL Connection scheduler */ +static inline struct hci_conn *hci_low_sent_acl(struct hci_dev *hdev, int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL; - int num = 0, min = ~0; + unsigned int num = 0, min = ~0; struct list_head *p; /* We don't have to lock device here. Connections are always @@ -1171,20 +1180,22 @@ struct hci_conn *c; c = list_entry(p, struct hci_conn, list); - if (c->type != type || c->state != BT_CONNECTED + BT_DBG("c->type %d c->state %d len(c->data_q) %d min %d c->sent %d", + c->type, c->state, skb_queue_len(&c->data_q), min, atomic_read(&c->sent)); + + if (c->type != ACL_LINK || c->state != BT_CONNECTED || skb_queue_empty(&c->data_q)) continue; num++; - if (c->sent < min) { - min = c->sent; + if (atomic_read(&c->sent) < min) { + min = atomic_read(&c->sent); conn = c; } } if (conn) { - int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt); - int q = cnt / num; + int q = hdev->acl_cnt / num; *quote = q ? q : 1; } else *quote = 0; @@ -1204,7 +1215,7 @@ /* Kill stalled connections */ list_for_each(p, &h->list) { c = list_entry(p, struct hci_conn, list); - if (c->type == ACL_LINK && c->sent) { + if (c->type == ACL_LINK && atomic_read(&c->sent)) { BT_ERR("%s killing stalled ACL connection %s", hdev->name, batostr(&c->dst)); hci_acl_disconn(c, 0x13); @@ -1227,7 +1238,7 @@ hci_acl_tx_to(hdev); } - while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { + while (hdev->acl_cnt && (conn = hci_low_sent_acl(hdev, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); @@ -1237,28 +1248,61 @@ hdev->acl_last_tx = jiffies; hdev->acl_cnt--; - conn->sent++; + atomic_inc(&conn->sent); } } } -/* Schedule SCO */ +/* HCI SCO Connection scheduler */ + static inline void hci_sched_sco(struct hci_dev *hdev) { - struct hci_conn *conn; + struct hci_conn_hash *h = &hdev->conn_hash; struct sk_buff *skb; - int quote; - + struct list_head *p; + struct hci_conn *c; + ktime_t now, pkt_time; + BT_DBG("%s", hdev->name); + + /* We don't have to lock device here. Connections are always + added and removed with TX task disabled. */ + list_for_each(p, &h->list) { + c = list_entry(p, struct hci_conn, list); + + /* SCO scheduling algorithm makes sure there is never more than + 1 outstanding packet for each connection */ - while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { - while (quote-- && (skb = skb_dequeue(&conn->data_q))) { - BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(skb); + if (c->type != SCO_LINK) + continue; - conn->sent++; - if (conn->sent == ~0) - conn->sent = 0; + if (atomic_read(&c->sent) >= 1) + continue; + + if (c->state != BT_CONNECTED) + continue; + + if (atomic_read(&hdev->sco_cnt) <= 0) + continue; + + if ((skb = skb_dequeue(&c->data_q)) == NULL) + continue; + + hci_send_frame(skb); + + atomic_inc(&c->sent); + atomic_dec(&hdev->sco_cnt); + + pkt_time = ktime_set(0, NSEC_PER_SEC / 16000 * (skb->len - HCI_SCO_HDR_SIZE)); + now = c->tx_timer.base->get_time(); + + c->tx_timer.expires.tv64 += pkt_time.tv64; + if (c->tx_timer.expires.tv64 > now.tv64) { + hrtimer_restart(&c->tx_timer); + } else { + /* Timer is to expire in the past - force timer expiration. + this can happen if timer base precision is less than pkt_time */ + c->tx_timer.function(&c->tx_timer); } } } @@ -1270,14 +1314,14 @@ read_lock(&hci_task_lock); - BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt); + BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, atomic_read(&hdev->sco_cnt)); /* Schedule queues and send stuff to HCI driver */ - hci_sched_acl(hdev); - hci_sched_sco(hdev); + hci_sched_acl(hdev); + /* Send next queued raw (unknown type) packet */ while ((skb = skb_dequeue(&hdev->raw_q))) hci_send_frame(skb); --- linux-source-2.6.22-2.6.22.orig/net/bluetooth/hci_conn.c +++ linux-source-2.6.22-2.6.22/net/bluetooth/hci_conn.c @@ -165,6 +165,26 @@ hci_conn_enter_sniff_mode(conn); } +static enum hrtimer_restart hci_sco_tx_timer(struct hrtimer *timer) +{ + struct hci_conn *conn = container_of(timer, struct hci_conn, tx_timer); +#ifdef CONFIG_BT_HCI_CORE_DEBUG + ktime_t now = timer->base->get_time(); + + BT_DBG("%s, conn %p, time %5lu.%06lu", conn->hdev->name, conn, + (unsigned long) now.tv64, + do_div(now.tv64, NSEC_PER_SEC) / 1000); +#endif + + if (atomic_read(&conn->sent) > 0) { + atomic_dec(&conn->sent); + atomic_inc(&conn->hdev->sco_cnt); + hci_sched_tx(conn->hdev); + } + return HRTIMER_NORESTART; +} + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) { struct hci_conn *conn; @@ -185,6 +205,11 @@ skb_queue_head_init(&conn->data_q); + hrtimer_init(&conn->tx_timer, CLOCK_MONOTONIC, HRTIMER_NORESTART); + + if(type == SCO_LINK) + conn->tx_timer.function = hci_sco_tx_timer; + init_timer(&conn->disc_timer); conn->disc_timer.function = hci_conn_timeout; conn->disc_timer.data = (unsigned long) conn; @@ -194,6 +219,7 @@ conn->idle_timer.data = (unsigned long) conn; atomic_set(&conn->refcnt, 0); + atomic_set(&conn->sent, 0); hci_dev_hold(hdev); @@ -220,6 +246,8 @@ del_timer(&conn->disc_timer); + hrtimer_cancel(&conn->tx_timer); + if (conn->type == SCO_LINK) { struct hci_conn *acl = conn->link; if (acl) { @@ -232,7 +260,7 @@ sco->link = NULL; /* Unacked frames */ - hdev->acl_cnt += conn->sent; + hdev->acl_cnt += atomic_read(&conn->sent); } tasklet_disable(&hdev->tx_task); --- linux-source-2.6.22-2.6.22.orig/net/bluetooth/hci_event.c +++ linux-source-2.6.22-2.6.22/net/bluetooth/hci_event.c @@ -319,7 +319,7 @@ lv = (struct hci_rp_read_loc_version *) skb->data; if (lv->status) { - BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status); + BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lv->status); break; } @@ -381,7 +381,7 @@ } hdev->acl_cnt = hdev->acl_pkts; - hdev->sco_cnt = hdev->sco_pkts; + atomic_set(&hdev->sco_cnt, hdev->sco_pkts); BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); @@ -879,12 +879,9 @@ conn = hci_conn_hash_lookup_handle(hdev, handle); if (conn) { - conn->sent -= count; + atomic_sub(count, &conn->sent); - if (conn->type == SCO_LINK) { - if ((hdev->sco_cnt += count) > hdev->sco_pkts) - hdev->sco_cnt = hdev->sco_pkts; - } else { + if (conn->type == ACL_LINK) { if ((hdev->acl_cnt += count) > hdev->acl_pkts) hdev->acl_cnt = hdev->acl_pkts; } --- linux-source-2.6.22-2.6.22.orig/net/bluetooth/sco.c +++ linux-source-2.6.22-2.6.22/net/bluetooth/sco.c @@ -53,7 +53,13 @@ #define BT_DBG(D...) #endif -#define VERSION "0.5" +#define VERSION "0.6" + +#define MAX_SCO_TXBUFS 200 +#define MAX_SCO_RXBUFS 200 + +#define DEFAULT_SCO_TXBUFS 5 +#define DEFAULT_SCO_RXBUFS 5 static const struct proto_ops sco_sock_ops; @@ -69,6 +75,33 @@ static void sco_sock_close(struct sock *sk); static void sco_sock_kill(struct sock *sk); +/* + * Write buffer destructor automatically called from kfree_skb. + */ +void sco_sock_wfree(struct sk_buff *skb) +{ + struct sock *sk = skb->sk; + + atomic_dec(&sk->sk_wmem_alloc); + sk->sk_write_space(sk); + sock_put(sk); +} + +static void sco_sock_write_space(struct sock *sk) +{ + read_lock(&sk->sk_callback_lock); + + if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { + if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) + wake_up_interruptible(sk->sk_sleep); + + if (sock_writeable(sk)) + sk_wake_async(sk, 2, POLL_OUT); + } + + read_unlock(&sk->sk_callback_lock); +} + /* ---- SCO timers ---- */ static void sco_sock_timeout(unsigned long arg) { @@ -234,33 +267,55 @@ { struct sco_conn *conn = sco_pi(sk)->conn; struct sk_buff *skb; - int err, count; - - /* Check outgoing MTU */ - if (len > conn->mtu) - return -EINVAL; + int err; BT_DBG("sk %p len %d", sk, len); - count = min_t(unsigned int, conn->mtu, len); - if (!(skb = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err))) + if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) return err; - if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) { + /* fix sk_wmem_alloc value : by default it is increased by skb->truesize, but + we want it only increased by 1 */ + atomic_sub(skb->truesize - 1, &sk->sk_wmem_alloc); + /* fix destructor */ + skb->destructor = sco_sock_wfree; + + if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { err = -EFAULT; goto fail; } - if ((err = hci_send_sco(conn->hcon, skb)) < 0) - return err; + err = hci_send_sco(conn->hcon, skb); + + if (err < 0) + goto fail; - return count; + return len; fail: kfree_skb(skb); return err; } +static int sco_sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + BT_DBG("sock %p, sk_rcvbuf %d, qlen %d", sk, sk->sk_rcvbuf, skb_queue_len(&sk->sk_receive_queue)); + + if (skb_queue_len(&sk->sk_receive_queue) + 1 > (unsigned)sk->sk_rcvbuf) + return -ENOMEM; + + skb->dev = NULL; + skb->sk = sk; + skb->destructor = NULL; + + skb_queue_tail(&sk->sk_receive_queue, skb); + + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_data_ready(sk, 1); + + return 0; +} + static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) { struct sock *sk = sco_chan_get(conn); @@ -273,7 +328,7 @@ if (sk->sk_state != BT_CONNECTED) goto drop; - if (!sock_queue_rcv_skb(sk, skb)) + if (!sco_sock_queue_rcv_skb(sk, skb)) return; drop: @@ -328,7 +383,6 @@ BT_DBG("sk %p", sk); skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); } static void sco_sock_cleanup_listen(struct sock *parent) @@ -426,6 +480,10 @@ INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_destruct = sco_sock_destruct; + sk->sk_write_space = sco_sock_write_space; + + sk->sk_sndbuf = DEFAULT_SCO_TXBUFS; + sk->sk_rcvbuf = DEFAULT_SCO_RXBUFS; sk->sk_sndtimeo = SCO_CONN_TIMEOUT; sock_reset_flag(sk, SOCK_ZAPPED); @@ -656,6 +714,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk = sock->sk; + u32 opt; int err = 0; BT_DBG("sk %p", sk); @@ -663,6 +722,32 @@ lock_sock(sk); switch (optname) { + case SO_SNDBUF: + if (get_user(opt, (u32 __user *) optval)) { + err = -EFAULT; + break; + } + if (opt > MAX_SCO_TXBUFS) { + err = -EINVAL; + break; + } + + sk->sk_sndbuf = opt; + /* Wake up sending tasks if we upped the value */ + sk->sk_write_space(sk); + break; + case SO_RCVBUF: + if (get_user(opt, (u32 __user *) optval)) { + err = -EFAULT; + break; + } + if (opt > MAX_SCO_RXBUFS) { + err = -EINVAL; + break; + } + + sk->sk_rcvbuf = opt; + break; default: err = -ENOPROTOOPT; break; @@ -678,6 +763,7 @@ struct sco_options opts; struct sco_conninfo cinfo; int len, err = 0; + int val; BT_DBG("sk %p", sk); @@ -687,6 +773,24 @@ lock_sock(sk); switch (optname) { + case SO_RCVBUF: + val = sk->sk_rcvbuf; + + len = min_t(unsigned int, len, sizeof(val)); + if (copy_to_user(optval, (char *) &val, len)) + err = -EFAULT; + + break; + + case SO_SNDBUF: + val = sk->sk_sndbuf; + + len = min_t(unsigned int, len, sizeof(val)); + if (copy_to_user(optval, (char *) &val, len)) + err = -EFAULT; + + break; + case SCO_OPTIONS: if (sk->sk_state != BT_CONNECTED) { err = -ENOTCONN; @@ -698,7 +802,7 @@ BT_DBG("mtu %d", opts.mtu); len = min_t(unsigned int, len, sizeof(opts)); - if (copy_to_user(optval, (char *)&opts, len)) + if (copy_to_user(optval, (char *) &opts, len)) err = -EFAULT; break; @@ -713,7 +817,7 @@ memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); len = min_t(unsigned int, len, sizeof(cinfo)); - if (copy_to_user(optval, (char *)&cinfo, len)) + if (copy_to_user(optval, (char *) &cinfo, len)) err = -EFAULT; break; --- linux-source-2.6.22-2.6.22.orig/net/decnet/dn_dev.c +++ linux-source-2.6.22-2.6.22/net/decnet/dn_dev.c @@ -815,7 +815,7 @@ for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { if (dn_idx < skip_naddr) - goto cont; + continue; if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, --- linux-source-2.6.22-2.6.22.orig/debian/config/i386/config.virtual +++ linux-source-2.6.22-2.6.22/debian/config/i386/config.virtual @@ -0,0 +1,587 @@ +# +# Config options for config.virtual automatically generated by splitconfig.pl +# +# CONFIG_60XX_WDT is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_ACENIC is not set +# CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_BATTERY is not set +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_SBS is not set +# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set +# CONFIG_ACPI_TOSHIBA is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_AMD is not set +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_EFFICEON is not set +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APM is not set +# CONFIG_APPLICOM is not set +# CONFIG_ARCNET is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATL1 is not set +# CONFIG_ATM is not set +# CONFIG_B44 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_IDEACPI is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BNX2 is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BT is not set +# CONFIG_CASSINI is not set +# CONFIG_CFG80211 is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_CPU5_WDT is not set +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DEV_PADLOCK=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CS5535_GPIO is not set +# CONFIG_DAB is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DECNET_NF_GRABULATOR is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DGRS is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DL2K is not set +# CONFIG_DRM is not set +# CONFIG_DVB_CORE is not set +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_ECONET is not set +# CONFIG_EDAC is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EPIC100 is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_CFB_COPYAREA=m +CONFIG_FB_CFB_FILLRECT=m +CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_CYBLA is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HECUBA is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_IMAC is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_NS558 is not set +CONFIG_GENERIC_PENDING_IRQ=y +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HID is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIPPI is not set +CONFIG_HOTPLUG_CPU=y +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HP100 is not set +CONFIG_HPET_EMULATE_RTC=y +# CONFIG_HWMON is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_GEODE is not set +# CONFIG_HW_RANDOM_VIA is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2O is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8K is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_IBM_ASM is not set +# CONFIG_IDE_PROC_FS is not set +# CONFIG_IEEE1394 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_INFINIBAND is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_WISTRON_BTNS is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IPC_NS is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IRDA is not set +# CONFIG_IRQBALANCE is not set +# CONFIG_ISA is not set +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISDN is not set +# CONFIG_IXGB is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KS0108 is not set +CONFIG_KVM=y +# CONFIG_LAPB is not set +CONFIG_LLC=m +CONFIG_LOCK_KERNEL=y +# CONFIG_LXT_PHY is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M686 is not set +# CONFIG_MAC80211 is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_MCA is not set +# CONFIG_MD_RAID10 is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MMC is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LIFEBOOK is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MTD is not set +# CONFIG_MWAVE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NCP_FS is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_DCCPPROBE is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NEW_LEDS is not set +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_NAT_H323 is not set +# CONFIG_NF_NAT_SIP is not set +# CONFIG_NF_NAT_SNMP_BASIC is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +# CONFIG_NS83820 is not set +# CONFIG_NSC_GPIO is not set +CONFIG_NTFS_RW=y +# CONFIG_PARIDE is not set +# CONFIG_PARPORT_AX88796 is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PC8736x_GPIO is not set +# CONFIG_PC87413_WDT is not set +# CONFIG_PCCARD is not set +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHONE is not set +# CONFIG_PLIP is not set +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_QLA3XXX is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_R3964 is not set +# CONFIG_R8169 is not set +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_RFKILL is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RTC=y +# CONFIG_RTC_CLASS is not set +# CONFIG_S2IO is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_SC92031 is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_TGT is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_SMP=y +# CONFIG_SMSC37B787_WDT is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MTS64 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_PORTMAN2X4 is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SOC is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +CONFIG_STOP_MACHINE=y +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SUSPEND_SMP=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TIPAR is not set +# CONFIG_TLAN is not set +# CONFIG_TOSHIBA is not set +# CONFIG_TR is not set +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_GADGET is not set +# CONFIG_USB_HID is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LIBUSUAL is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USS720 is not set +# CONFIG_UTS_NS is not set +CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.20-16.30-generic" +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_W1 is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83697HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WDTPCI is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_X25 is not set +CONFIG_X86_ALIGNMENT_16=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_F00F_BUG=y +CONFIG_X86_HT=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_TRAMPOLINE=y +# CONFIG_YELLOWFIN is not set --- linux-source-2.6.22-2.6.22.orig/debian/config/i386/config +++ linux-source-2.6.22-2.6.22/debian/config/i386/config @@ -0,0 +1,1104 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_4KSTACKS is not set +CONFIG_AC97_BUS=m +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_AGP=m +CONFIG_AGP_INTEL=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_PIIX=m +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLOCK=y +CONFIG_BONDING=m +CONFIG_BOOT_IOREMAP=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BUG=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPAT_VDSO=y +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_DCDBAS=m +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DELL_RBU=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DOUBLEFAULT=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECRYPT_FS=m +# CONFIG_EDD is not set +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSE_FS=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GAMEPORT=m +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_TIME=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HOTPLUG=y +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM_INTEL=m +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INTEL_IOATDMA=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISO9660_FS=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KTIME_SCALAR=y +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LBD=y +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +# CONFIG_LKDTM is not set +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +# CONFIG_LSF is not set +# CONFIG_M386 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +# CONFIG_MEFFICEON is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_SUBPARTITION=y +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_PS2=m +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +CONFIG_MTRR=y +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NR_QUICK=1 +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +CONFIG_NVRAM=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +# CONFIG_OSS_OBSOLETE is not set +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PARAVIRT=y +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_VIA is not set +CONFIG_PCI=y +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +CONFIG_PLIST=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SYSFS_DEPRECATED=y +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QNX4FS_FS=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SCHEDSTATS is not set +CONFIG_SCSI=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SK98LIN is not set +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_INTEL8X0=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RTCTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SOUND=m +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_PAS is not set +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_SB is not set +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_STANDALONE=y +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TUN=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OTG is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_TEST is not set +CONFIG_USB_UHCI_HCD=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIDEO_SELECT=y +CONFIG_VLAN_8021Q=m +CONFIG_VM86=y +CONFIG_VMI=y +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WRAPPER_PRINT is not set +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_GX_SUSPMOD=m +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_LONGHAUL=m +CONFIG_X86_LONGRUN=m +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_MODEL=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +# CONFIG_X86_NUMAQ is not set +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +# CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI is not set +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_VOYAGER is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-source-2.6.22-2.6.22.orig/debian/config/i386/config.generic +++ linux-source-2.6.22-2.6.22/debian/config/i386/config.generic @@ -0,0 +1,1994 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP_PROC_SLEEP=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADVANTECH_WDT=m +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_AZTCD=m +CONFIG_B44=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CDU535=m +CONFIG_CD_NO_IDESCSI=y +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +# CONFIG_COMPUTONE is not set +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=m +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +CONFIG_EDAC_R82600=m +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_GSCD=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPPP_FILTER=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQBALANCE is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISP16_CDI=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KVM=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_LEDS_WRAP=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LOCK_KERNEL=y +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCDX=m +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +# CONFIG_NETLABEL is not set +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI52=m +CONFIG_NI65=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPTCD=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRISM54=m +CONFIG_PROTEON=m +CONFIG_PSS_MIXER=y +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SJCD=m +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKISA=m +CONFIG_SKY2=m +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=m +CONFIG_SND_AD1848_LIB=m +CONFIG_SND_AD1889=m +CONFIG_SND_ADLIB=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS100=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT2320=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4231=m +CONFIG_SND_CS4231_LIB=m +CONFIG_SND_CS4232=m +CONFIG_SND_CS4236=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_DT019X=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ES1688=m +CONFIG_SND_ES18XX=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_GUSCLASSIC=m +CONFIG_SND_GUSEXTREME=m +CONFIG_SND_GUSMAX=m +CONFIG_SND_GUS_SYNTH=m +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIRO=m +CONFIG_SND_MIXART=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3SA2=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL4_LIB=m +CONFIG_SND_OPTI92X_AD1848=m +CONFIG_SND_OPTI92X_CS4231=m +CONFIG_SND_OPTI93X=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL=y +CONFIG_SND_SB8=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SGALAXY=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SSCAPE=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_WAVEFRONT=m +CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL=y +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUSPEND_SMP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIPAR=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_F00F_BUG=y +CONFIG_X86_HT=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-source-2.6.22-2.6.22.orig/debian/config/i386/config.server +++ linux-source-2.6.22-2.6.22/debian/config/i386/config.server @@ -0,0 +1,2000 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP_PROC_SLEEP=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADVANTECH_WDT=m +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_AZTCD=m +CONFIG_B44=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CDU535=m +CONFIG_CD_NO_IDESCSI=y +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +# CONFIG_COMPUTONE is not set +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=m +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +CONFIG_EDAC_R82600=m +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_GSCD=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPC_NS=y +CONFIG_IPPP_FILTER=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQBALANCE is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISP16_CDI=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KVM=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_LEDS_WRAP=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LOCK_KERNEL=y +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +# CONFIG_M486 is not set +# CONFIG_M586 is not set +CONFIG_M686=y +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCDX=m +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +CONFIG_NETLABEL=y +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI52=m +CONFIG_NI65=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPTCD=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +# CONFIG_PREEMPT_BKL is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PRISM54=m +CONFIG_PROTEON=m +CONFIG_PSS_MIXER=y +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SJCD=m +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKISA=m +CONFIG_SKY2=m +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=m +CONFIG_SND_AD1848_LIB=m +CONFIG_SND_AD1889=m +CONFIG_SND_ADLIB=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS100=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT2320=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4231=m +CONFIG_SND_CS4231_LIB=m +CONFIG_SND_CS4232=m +CONFIG_SND_CS4236=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_DT019X=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ES1688=m +CONFIG_SND_ES18XX=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_GUSCLASSIC=m +CONFIG_SND_GUSEXTREME=m +CONFIG_SND_GUSMAX=m +CONFIG_SND_GUS_SYNTH=m +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIRO=m +CONFIG_SND_MIXART=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3SA2=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL4_LIB=m +CONFIG_SND_OPTI92X_AD1848=m +CONFIG_SND_OPTI92X_CS4231=m +CONFIG_SND_OPTI93X=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL=y +CONFIG_SND_SB8=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SGALAXY=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SSCAPE=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_WAVEFRONT=m +CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL=y +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUSPEND_SMP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIPAR=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_UTS_NS=y +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_HT=y +CONFIG_X86_PAE=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_TSC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-source-2.6.22-2.6.22.orig/debian/config/i386/config.386 +++ linux-source-2.6.22-2.6.22/debian/config/i386/config.386 @@ -0,0 +1,2000 @@ +# +# Config options for config.386 automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +CONFIG_60XX_WDT=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP_PROC_SLEEP=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADVANTECH_WDT=m +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +CONFIG_ASUS_LAPTOP=m +CONFIG_AT1700=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_AZTCD=m +CONFIG_B44=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLK_DEV_XD=m +CONFIG_BNX2=m +CONFIG_BPQETHER=m +CONFIG_BROADCOM_PHY=m +CONFIG_BROKEN_ON_SMP=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_C101=m +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +CONFIG_CDU31A=m +CONFIG_CDU535=m +CONFIG_CD_NO_IDESCSI=y +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CM206=m +CONFIG_COMPUTONE=m +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_COSA=m +CONFIG_CPU5_WDT=m +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DEPCA=m +CONFIG_DE_AOC=y +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DM9102=m +CONFIG_DMASCC=m +CONFIG_DONGLE=y +# CONFIG_DONGLE_OLD is not set +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_E2100=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=m +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +CONFIG_EDAC_R82600=m +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EWRK3=m +CONFIG_FARSYNC=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMAC=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FTL=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GEN_RTC=m +CONFIG_GEN_RTC_X=y +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_GSCD=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +CONFIG_HERMES=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_ELEKTOR=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_PROC_FS=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +# CONFIG_INPUT_YEALINK is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPPP_FILTER=y +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRPORT_SIR=m +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_LOOP=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISP16_CDI=m +CONFIG_ISTALLION=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_K8_NB=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KVM=m +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_NET48XX=m +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_LEDS_WRAP=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=y +CONFIG_LNE390=m +CONFIG_LP486E=m +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_M486=y +# CONFIG_M586 is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MADGEMC=m +CONFIG_MARVELL_PHY=m +CONFIG_MATH_EMULATION=y +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +CONFIG_MCDX=m +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDA_CONSOLE=m +CONFIG_MD_RAID10=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MINIX_FS=m +CONFIG_MIXCOMWD=m +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2000=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +# CONFIG_NETLABEL is not set +CONFIG_NETROM=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_FC=y +CONFIG_NET_ISA=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_POCKET=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NI5010=m +CONFIG_NI52=m +CONFIG_NI65=m +# CONFIG_NORTEL_HERMES is not set +# CONFIG_NO_HZ is not set +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPTCD=m +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_EFAR=m +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_QDI=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_HERMES is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCMCIA_XIRTULIP=m +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PLIP=m +# CONFIG_PLX_HERMES is not set +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PPPOATM=m +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRISM54=m +CONFIG_PROTEON=m +CONFIG_PSS_MIXER=y +CONFIG_QLA3XXX=m +CONFIG_QSEMI_PHY=m +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_RISCOM8=m +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RTC=m +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SBPCD=m +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FD_MCS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MCA_53C9X=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SIGMATEL_FIR=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SJCD=m +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKISA=m +CONFIG_SKY2=m +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +# CONFIG_SMP is not set +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=m +CONFIG_SND_AD1848_LIB=m +CONFIG_SND_AD1889=m +CONFIG_SND_ADLIB=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS100=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT2320=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4231=m +CONFIG_SND_CS4231_LIB=m +CONFIG_SND_CS4232=m +CONFIG_SND_CS4236=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_DT019X=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ES1688=m +CONFIG_SND_ES18XX=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_GUSCLASSIC=m +CONFIG_SND_GUSEXTREME=m +CONFIG_SND_GUSMAX=m +CONFIG_SND_GUS_SYNTH=m +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIRO=m +CONFIG_SND_MIXART=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3SA2=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL4_LIB=m +CONFIG_SND_OPTI92X_AD1848=m +CONFIG_SND_OPTI92X_CS4231=m +CONFIG_SND_OPTI93X=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL=y +CONFIG_SND_SB8=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SGALAXY=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SSCAPE=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_WAVEFRONT=m +CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL=y +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_SPIDEV is not set +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STALLION=m +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYSV68_PARTITION=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIPAR=m +CONFIG_TLAN=m +# CONFIG_TMD_HERMES is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +CONFIG_USB_DSBR=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +CONFIG_VORTEX=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_F00F_BUG=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZNET=m --- linux-source-2.6.22-2.6.22.orig/debian/config/ia64/config +++ linux-source-2.6.22-2.6.22/debian/config/ia64/config @@ -0,0 +1,2382 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_64BIT=y +# CONFIG_6PACK is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +CONFIG_ACORN_PARTITION_ADFS=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +CONFIG_ACORN_PARTITION_EESOX=y +CONFIG_ACORN_PARTITION_ICS=y +CONFIG_ACORN_PARTITION_POWERTEC=y +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_HP_ZX1=m +CONFIG_AGP_I460=m +# CONFIG_AGP_SGI_TIOCA is not set +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO_CS=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +# CONFIG_ARCNET_COM90xx is not set +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +# CONFIG_ARCNET_RIM_I is not set +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +CONFIG_ATA_NONSTANDARD=y +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +# CONFIG_ATM is not set +CONFIG_ATMEL=m +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_ARCH=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B44=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SGIIOC4=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BONDING=m +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_H4 is not set +CONFIG_BT_HCIUSB=m +# CONFIG_BT_HCIUSB_SCO is not set +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +# CONFIG_BT_RFCOMM_TTY is not set +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +CONFIG_CODA_FS_OLD_API=y +CONFIG_COMPAT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +# CONFIG_CYCLADES is not set +# CONFIG_CYCLADES_SYNC is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DGRS=m +# CONFIG_DIGIEPCA is not set +# CONFIG_DISABLE_VHPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +# CONFIG_DONGLE is not set +CONFIG_DRM=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +# CONFIG_DSCC4_PCISYNC is not set +# CONFIG_DSCC4_PCI_RST is not set +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +CONFIG_EEPRO100=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_PCDP=y +CONFIG_EFI_RTC=y +CONFIG_EFI_VARS=m +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +CONFIG_FB_KYRO=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +# CONFIG_HAPPYMEAL is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +# CONFIG_HIPPI is not set +CONFIG_HOLES_IN_ZONE=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SGI is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_HP100 is not set +# CONFIG_HPET is not set +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HP_SIMETH is not set +# CONFIG_HP_SIMSERIAL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_IA32_SUPPORT=y +CONFIG_IA64=y +# CONFIG_IA64_ACPI_CPUFREQ is not set +# CONFIG_IA64_CYCLONE is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_ESI is not set +CONFIG_IA64_GENERIC=y +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_HP_SIM is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set +CONFIG_IA64_MCA_RECOVERY=m +CONFIG_IA64_MC_ERR_INJECT=m +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PALINFO=m +CONFIG_IA64_PRINT_HAZARDS=y +# CONFIG_IA64_SGI_SN2 is not set +CONFIG_IA64_SGI_SN_XP=m +CONFIG_IA64_UNCACHED_ALLOCATOR=y +CONFIG_IBMOL=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INET=y +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +# CONFIG_INET_AH is not set +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +# CONFIG_INET_ESP is not set +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_IOSAPIC=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_DEBUG is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_ULTRA is not set +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRQ_PER_CPU=y +CONFIG_IRTTY_SIR=m +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFS_DEBUG=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +# CONFIG_JOYSTICK_IFORCE_232 is not set +# CONFIG_JOYSTICK_IFORCE_USB is not set +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_LANMEDIA=m +# CONFIG_LAPB is not set +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LDM_DEBUG=y +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCS_FIR=m +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MIGRATION=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +# CONFIG_MKISS is not set +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +# CONFIG_MMC is not set +# CONFIG_MMTIMER is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSNDCLAS_INIT_FILE="m" +CONFIG_MSNDCLAS_PERM_FILE="m" +CONFIG_MSNDPIN_INIT_FILE="m" +CONFIG_MSNDPIN_PERM_FILE="m" +CONFIG_MSPEC=m +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NETROM=m +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NODES_SHIFT=8 +# CONFIG_NORTEL_HERMES is not set +CONFIG_NR_CPUS=64 +CONFIG_NR_QUICK=1 +CONFIG_NS83820=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NUMA=y +CONFIG_N_HDLC=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +# CONFIG_OSS_OBSOLETE is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +CONFIG_PARIDE_EPATC8=y +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +# CONFIG_PCI_MSI is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PERFMON=y +CONFIG_PGTABLE_3=y +# CONFIG_PGTABLE_4 is not set +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_SYSFS_DEPRECATED=y +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_SCHED_SMT is not set +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_MD5 is not set +CONFIG_SCTP_HMAC_NONE=y +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_SGI_IOC3=m +CONFIG_SERIAL_SGI_IOC4=m +CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC3=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_MBCS=m +CONFIG_SGI_PARTITION=y +CONFIG_SGI_SN=y +CONFIG_SGI_SNSC=y +CONFIG_SGI_TIOCX=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_SMP=y +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SOUND=y +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPECIALIX is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SWIOTLB=y +# CONFIG_SX is not set +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +CONFIG_TIME_INTERPOLATION=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPAR=m +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMS380TR is not set +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_EZUSB=y +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLSI_FIR is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +# CONFIG_WATCHDOG is not set +CONFIG_WDC_ALI15X3=y +CONFIG_WINBOND_840=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +CONFIG_XFS_SECURITY=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-source-2.6.22-2.6.22.orig/debian/config/ia64/config.itanium +++ linux-source-2.6.22-2.6.22/debian/config/ia64/config.itanium @@ -0,0 +1,7 @@ +# +# Config options for config.itanium automatically generated by splitconfig.pl +# +CONFIG_IA64_BRL_EMU=y +CONFIG_IA64_L1_CACHE_SHIFT=6 +CONFIG_ITANIUM=y +# CONFIG_MCKINLEY is not set --- linux-source-2.6.22-2.6.22.orig/debian/config/ia64/config.mckinley +++ linux-source-2.6.22-2.6.22/debian/config/ia64/config.mckinley @@ -0,0 +1,6 @@ +# +# Config options for config.mckinley automatically generated by splitconfig.pl +# +CONFIG_IA64_L1_CACHE_SHIFT=7 +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y --- linux-source-2.6.22-2.6.22.orig/debian/config/powerpc/config +++ linux-source-2.6.22-2.6.22/debian/config/powerpc/config @@ -0,0 +1,2420 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADB_PMU=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALI_FIR=m +CONFIG_ALTIVEC=y +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLE_AIRPORT=m +CONFIG_APPLICOM=m +# CONFIG_APUS is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_GENERIC=m +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_TCP=m +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_ARCH=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_B44=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BONDING=m +# CONFIG_BOOTX_TEXT is not set +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CARDBUS=y +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +# CONFIG_CPM2 is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUGGER is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMA_ENGINE=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=m +CONFIG_EEPRO100=m +# CONFIG_EFI_PARTITION is not set +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_EMBEDDED6xx is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=y +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=y +CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_IBM_GXT4500=m +CONFIG_FB_KYRO=m +CONFIG_FB_MACMODES=y +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_OF=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +CONFIG_FB_TRIDENT_ACCEL=y +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=y +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIPPI=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_PCI is not set +CONFIG_HP100=m +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_HVC_RTAS is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +CONFIG_I2C_POWERMAC=y +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_IBMOL=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_GENERIC is not set +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRQ_PER_CPU=y +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_OF=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_N_HDLC=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +# CONFIG_OSS_OBSOLETE is not set +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_MSI=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +CONFIG_PMAC_RACKMETER=m +# CONFIG_PM_DEBUG is not set +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_SYSFS_DEPRECATED=y +# CONFIG_PNPACPI is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPC=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_EARLY_DEBUG is not set +CONFIG_PPC_FPU=y +CONFIG_PPC_I8259=y +CONFIG_PPC_MERGE=y +CONFIG_PPC_MULTIPLATFORM=y +CONFIG_PPC_NATIVE=y +CONFIG_PPC_OF=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PM_NEEDS_RTC_LIB=y +CONFIG_PPC_RTAS=y +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_UDBG_16550=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PQ2ADS is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRISM54=m +CONFIG_PROC_DEVICETREE=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RTAS_PROC=y +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=m +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=m +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_OF_PLATFORM=m +CONFIG_SERIO=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_POWERMAC=m +CONFIG_SND_POWERMAC_AUTO_DRC=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SOUND=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSFDC=m +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEKRAM_DONGLE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPAR=m +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +# CONFIG_UCC_SLOW is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +CONFIG_VGASTATE=m +# CONFIG_VGA_CONSOLE is not set +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLSI_FIR=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN=y +# CONFIG_WANT_DEVICE_TREE is not set +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_RTAS=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WINDFARM=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-source-2.6.22-2.6.22.orig/debian/config/powerpc/config.powerpc +++ linux-source-2.6.22-2.6.22/debian/config/powerpc/config.powerpc @@ -0,0 +1,190 @@ +# +# Config options for config.powerpc automatically generated by splitconfig.pl +# +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_6xx=y +CONFIG_ACT200L_DONGLE_OLD=m +CONFIG_ACTISYS_DONGLE_OLD=m +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU_LED=y +# CONFIG_ADB_PMU_LED_IDE is not set +# CONFIG_ADVANCED_OPTIONS is not set +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_ANSLCD=m +CONFIG_APM_EMULATION=m +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_BAYCOM_EPP=m +# CONFIG_BDI_SWITCH is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BMAC=m +CONFIG_BOOT_LOAD=0x00800000 +CONFIG_BRIQ_PANEL=m +CONFIG_BROKEN_ON_SMP=y +CONFIG_CLASSIC32=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_PMAC=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DONGLE_OLD=y +# CONFIG_E200 is not set +CONFIG_ESI_DONGLE_OLD=m +CONFIG_FB_CONTROL=y +CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y +CONFIG_FB_PLATINUM=y +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_VALKYRIE=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FSL_SOC=y +# CONFIG_GENERIC_IOMAP is not set +CONFIG_GENERIC_NVRAM=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_GIRBIL_DONGLE_OLD=m +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_HUGETLB_PAGE is not set +CONFIG_I2C_HYDRA=m +CONFIG_I2C_MPC=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_IBMLS=m +CONFIG_INPUT_ADBHID=y +CONFIG_IRPORT_SIR=m +# CONFIG_ISA is not set +CONFIG_ISTALLION=m +CONFIG_KERNEL_START=0xc0000000 +CONFIG_LANMEDIA=m +# CONFIG_LBD is not set +CONFIG_LITELINK_DONGLE_OLD=m +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_LSF is not set +CONFIG_MA600_DONGLE_OLD=m +CONFIG_MACE=m +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_MAC_FLOPPY=m +CONFIG_MCP2120_DONGLE_OLD=m +# CONFIG_MMIO_NVRAM is not set +CONFIG_MV643XX_ETH=m +CONFIG_NVRAM=y +CONFIG_OLD_BELKIN_DONGLE_OLD=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PATA_MPC52xx=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_XIRTULIP=m +CONFIG_PMAC_APM_EMU=m +CONFIG_PMAC_BACKLIGHT=y +CONFIG_PMAC_BACKLIGHT_LEGACY=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PPC32=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_PPC64 is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +CONFIG_PPC_CHRP=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_EFIKA=y +# CONFIG_PPC_INDIRECT_IO is not set +CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set +CONFIG_PPC_LITE5200=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_MPC106=y +CONFIG_PPC_MPC5200=y +# CONFIG_PPC_MPC5200_BUGFIX is not set +CONFIG_PPC_MPC52xx=y +CONFIG_PPC_STD_MMU_32=y +CONFIG_PSS_MIXER=y +CONFIG_RISCOM8=m +# CONFIG_RTAS_ERROR_LOGGING is not set +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_MAC53C94=m +CONFIG_SCSI_MESH=m +CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_NSP32=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SENSORS_AMS=m +CONFIG_SENSORS_AMS_I2C=y +CONFIG_SENSORS_AMS_PMU=y +CONFIG_SENSORS_M41T00=m +CONFIG_SERIAL_MPC52xx=m +CONFIG_SERIAL_PMACZILOG=m +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIO_I8042=y +# CONFIG_SMP is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_SOUND_AEDSP16=m +# CONFIG_SOUND_DMAP is not set +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_PAS is not set +CONFIG_SOUND_PSS=m +# CONFIG_SOUND_SB is not set +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPI_MPC52xx_PSC=m +CONFIG_STALLION=m +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_TAU=y +# CONFIG_TAU_AVERAGE is not set +# CONFIG_TAU_INT is not set +CONFIG_TEKRAM_DONGLE_OLD=m +CONFIG_THERM_ADT746X=m +CONFIG_THERM_WINDTUNNEL=m +CONFIG_TLAN=m +CONFIG_TOSHIBA_FIR=m +# CONFIG_UDBG_RTAS_CONSOLE is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_OHCI_HCD_PPC_SOC is not set +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m --- linux-source-2.6.22-2.6.22.orig/debian/config/powerpc/config.powerpc-smp +++ linux-source-2.6.22-2.6.22/debian/config/powerpc/config.powerpc-smp @@ -0,0 +1,180 @@ +# +# Config options for config.powerpc-smp automatically generated by splitconfig.pl +# +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_6xx=y +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU_LED=y +# CONFIG_ADB_PMU_LED_IDE is not set +# CONFIG_ADVANCED_OPTIONS is not set +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_ANSLCD=m +CONFIG_APM_EMULATION=m +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_BAYCOM_EPP=m +# CONFIG_BDI_SWITCH is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BMAC=m +CONFIG_BOOT_LOAD=0x00800000 +CONFIG_BRIQ_PANEL=m +CONFIG_CLASSIC32=y +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_PMAC=y +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_E200 is not set +CONFIG_FB_CONTROL=y +CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y +CONFIG_FB_PLATINUM=y +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_VALKYRIE=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FSL_SOC=y +# CONFIG_GENERIC_IOMAP is not set +CONFIG_GENERIC_NVRAM=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_I2C_HYDRA=m +CONFIG_I2C_MPC=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_IBMLS=m +CONFIG_INPUT_ADBHID=y +# CONFIG_IRQ_ALL_CPUS is not set +# CONFIG_ISA is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_LANMEDIA=m +# CONFIG_LBD is not set +CONFIG_LOCK_KERNEL=y +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_LSF is not set +CONFIG_MACE=m +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_MAC_FLOPPY=m +# CONFIG_MMIO_NVRAM is not set +CONFIG_MV643XX_ETH=m +CONFIG_NR_CPUS=4 +CONFIG_NVRAM=y +CONFIG_PARIDE_BPCK6=m +CONFIG_PATA_MPC52xx=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PMAC_APM_EMU=m +CONFIG_PMAC_BACKLIGHT=y +CONFIG_PMAC_BACKLIGHT_LEGACY=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PPC32=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_PPC64 is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +CONFIG_PPC_CHRP=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_EFIKA=y +# CONFIG_PPC_INDIRECT_IO is not set +CONFIG_PPC_INDIRECT_PCI=y +# CONFIG_PPC_INDIRECT_PCI_BE is not set +CONFIG_PPC_LITE5200=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_MPC106=y +CONFIG_PPC_MPC5200=y +# CONFIG_PPC_MPC5200_BUGFIX is not set +CONFIG_PPC_MPC52xx=y +CONFIG_PPC_STD_MMU_32=y +CONFIG_PREEMPT_BKL=y +CONFIG_PSS_MIXER=y +# CONFIG_RTAS_ERROR_LOGGING is not set +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_MAC53C94=m +CONFIG_SCSI_MESH=m +CONFIG_SCSI_MESH_RESET_DELAY_MS=4000 +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_NSP32=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SENSORS_AMS=m +CONFIG_SENSORS_AMS_I2C=y +CONFIG_SENSORS_AMS_PMU=y +CONFIG_SENSORS_M41T00=m +CONFIG_SERIAL_MPC52xx=m +CONFIG_SERIAL_PMACZILOG=m +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIO_I8042=y +CONFIG_SMP=y +CONFIG_SOUND_AEDSP16=m +# CONFIG_SOUND_DMAP is not set +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_PAS is not set +CONFIG_SOUND_PSS=m +# CONFIG_SOUND_SB is not set +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPI_MPC52xx_PSC=m +CONFIG_STOP_MACHINE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TASK_SIZE=0x80000000 +CONFIG_TAU=y +# CONFIG_TAU_AVERAGE is not set +# CONFIG_TAU_INT is not set +CONFIG_THERM_ADT746X=m +CONFIG_THERM_WINDTUNNEL=m +CONFIG_TLAN=m +CONFIG_TOSHIBA_FIR=m +# CONFIG_UDBG_RTAS_CONSOLE is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_OHCI_HCD_PPC_SOC is not set +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m --- linux-source-2.6.22-2.6.22.orig/debian/config/powerpc/config.powerpc64-smp +++ linux-source-2.6.22-2.6.22/debian/config/powerpc/config.powerpc64-smp @@ -0,0 +1,147 @@ +# +# Config options for config.powerpc64-smp automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +# CONFIG_ADB_PMU_LED is not set +CONFIG_ARCH_HAS_ILOG2_U64=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ATA_NONSTANDARD=y +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_CBE_CPUFREQ is not set +CONFIG_CBE_RAS=y +CONFIG_CBE_THERM=m +CONFIG_COMPAT=y +CONFIG_CPUSETS=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_PMAC64=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_EEH=y +CONFIG_EHEA=m +# CONFIG_FB_IMSTT is not set +CONFIG_FB_PS3=y +CONFIG_FB_PS3_DEFAULT_SIZE_M=18 +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_HCALL_STATS is not set +# CONFIG_HOTPLUG_CPU is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVCS=m +CONFIG_HVC_CONSOLE=y +CONFIG_HVC_DRIVER=y +CONFIG_HW_RANDOM_PASEMI=m +CONFIG_I2C_PASEMI=m +# CONFIG_I2O_CONFIG is not set +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_IBMEBUS=y +CONFIG_IBMVETH=m +CONFIG_IBMVIO=y +CONFIG_INFINIBAND_EHCA=m +CONFIG_INFINIBAND_IPATH=m +# CONFIG_IOMMU_VMERGE is not set +# CONFIG_IRQSTACKS is not set +CONFIG_IRQ_ALL_CPUS=y +CONFIG_KERNEL_START=0xc000000000000000 +CONFIG_KEYS_COMPAT=y +# CONFIG_LANMEDIA is not set +CONFIG_LOCK_KERNEL=y +CONFIG_LPARCFG=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MIGRATION=y +CONFIG_MMIO_NVRAM=y +CONFIG_MPIC_U3_HT_IRQS=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NODES_SHIFT=4 +CONFIG_NODES_SPAN_OTHER_NODES=y +CONFIG_NR_CPUS=32 +CONFIG_NUMA=y +# CONFIG_PASEMI_MAC is not set +CONFIG_PMAC_SMU=y +CONFIG_POWER3=y +CONFIG_POWER4=y +# CONFIG_POWER4_ONLY is not set +CONFIG_PPC64=y +CONFIG_PPC64_SWSUSP=y +# CONFIG_PPC_64K_PAGES is not set +CONFIG_PPC_970_NAP=y +CONFIG_PPC_CELL=y +# CONFIG_PPC_CELLEB is not set +CONFIG_PPC_CELL_NATIVE=y +CONFIG_PPC_DCR=y +CONFIG_PPC_DCR_MMIO=y +CONFIG_PPC_HAS_HASH_64K=y +CONFIG_PPC_IBM_CELL_BLADE=y +CONFIG_PPC_INDIRECT_IO=y +# CONFIG_PPC_INDIRECT_PCI is not set +# CONFIG_PPC_ISERIES is not set +CONFIG_PPC_MAPLE=y +CONFIG_PPC_MM_SLICES=y +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC52xx is not set +CONFIG_PPC_OF_PLATFORM_PCI=y +CONFIG_PPC_PASEMI=y +CONFIG_PPC_PASEMI_CPUFREQ=y +CONFIG_PPC_PASEMI_IOMMU=y +CONFIG_PPC_PASEMI_MDIO=m +CONFIG_PPC_PMAC64=y +CONFIG_PPC_PMI=m +CONFIG_PPC_PS3=y +CONFIG_PPC_PSERIES=y +CONFIG_PPC_SPLPAR=y +CONFIG_PREEMPT_BKL=y +# CONFIG_PS3_ADVANCED is not set +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_HTAB_SIZE=20 +CONFIG_PS3_PS3AV=y +CONFIG_PS3_SYS_MANAGER=y +CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y +CONFIG_RTAS_ERROR_LOGGING=y +CONFIG_RTAS_FLASH=m +CONFIG_SCANLOG=m +CONFIG_SCHED_SMT=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_IBMVSCSI=m +CONFIG_SCSI_IBMVSCSIS=m +CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIO_I8042 is not set +CONFIG_SMP=y +# CONFIG_SOUND_OSS is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPIDER_NET=m +CONFIG_SPU_BASE=y +CONFIG_SPU_FS=m +CONFIG_SPU_FS_64K_LS=y +CONFIG_STOP_MACHINE=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_THERM_PM72=m +CONFIG_U3_DART=y +CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_WINDFARM_PM112=m +CONFIG_WINDFARM_PM81=m +CONFIG_WINDFARM_PM91=m +CONFIG_XICS=y --- linux-source-2.6.22-2.6.22.orig/debian/config/lpia/config.lpia +++ linux-source-2.6.22-2.6.22/debian/config/lpia/config.lpia @@ -0,0 +1,3 @@ +# +# Config options for config.lpia automatically generated by splitconfig.pl +# --- linux-source-2.6.22-2.6.22.orig/debian/config/lpia/config +++ linux-source-2.6.22-2.6.22/debian/config/lpia/config @@ -0,0 +1,2385 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_4KSTACKS is not set +# CONFIG_60XX_WDT is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_AC3200 is not set +CONFIG_AC97_BUS=m +# CONFIG_ACENIC is not set +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y +# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +# CONFIG_ACQUIRE_WDT is not set +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_AMD is not set +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_EFFICEON is not set +CONFIG_AGP_INTEL=m +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_AIRO is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +CONFIG_ALI_FIR=m +# CONFIG_AMD8111_ETH is not set +CONFIG_ANON_INODES=y +# CONFIG_APM is not set +# CONFIG_APPLICOM is not set +# CONFIG_APRICOT is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_ARCNET is not set +# CONFIG_ARPD is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_AT1700 is not set +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +# CONFIG_ATL1 is not set +# CONFIG_ATM is not set +# CONFIG_ATMEL is not set +# CONFIG_AUDIT is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +# CONFIG_B44 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKLIGHT_PROGEAR is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BCM43XX is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_IDEPNP is not set +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_XD=m +CONFIG_BLOCK=y +# CONFIG_BNX2 is not set +CONFIG_BONDING=m +# CONFIG_BRIDGE is not set +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +# CONFIG_CASSINI is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +# CONFIG_CD_NO_IDESCSI is not set +CONFIG_CFG80211=m +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_ST is not set +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CISS_SCSI_TAPE is not set +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CODA_FS is not set +CONFIG_COMPAT_VDSO=y +# CONFIG_COMPUTONE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +# CONFIG_CPU5_WDT is not set +# CONFIG_CPUSETS is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRAMFS=y +# CONFIG_CRASH_DUMP is not set +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CS5535_GPIO=m +# CONFIG_CS89x0 is not set +# CONFIG_CYCLADES is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +# CONFIG_DCDBAS is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +# CONFIG_DELL_RBU is not set +# CONFIG_DEPCA is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DGRS is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_DMA_ENGINE is not set +CONFIG_DMI=y +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DOUBLEFAULT=y +# CONFIG_DRM is not set +# CONFIG_DTLK is not set +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +# CONFIG_ECRYPT_FS is not set +CONFIG_EDAC=m +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +CONFIG_EDAC_R82600=m +# CONFIG_EDD is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EFI is not set +# CONFIG_EFS_FS is not set +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_EPIC100 is not set +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +# CONFIG_ES3210 is not set +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +# CONFIG_EUROTECH_WDT is not set +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_CFB_COPYAREA=m +CONFIG_FB_CFB_FILLRECT=m +CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_CYBLA is not set +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HECUBA is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VESA is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +# CONFIG_FORCEDETH is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +# CONFIG_FUSION is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set +# CONFIG_FUSION_SPI is not set +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +# CONFIG_GFS2_FS is not set +CONFIG_GIRBIL_DONGLE=m +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +CONFIG_HANGCHECK_TIMER=m +# CONFIG_HAPPYMEAL is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_HERMES is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +# CONFIG_HOSTAP is not set +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HP100 is not set +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +# CONFIG_HPFS_FS is not set +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_POULSBO=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8K is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_IBM_ASM is not set +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +# CONFIG_INFINIBAND is not set +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +# CONFIG_IPX is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP is not set +CONFIG_IP_SCTP=m +# CONFIG_IP_VS is not set +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRQBALANCE=y +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +# CONFIG_ISAPNP is not set +CONFIG_ISA_DMA_API=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +# CONFIG_ITCO_WDT is not set +# CONFIG_IXGB is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_FS is not set +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KEXEC is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KS0108 is not set +CONFIG_KTIME_SCALAR=y +# CONFIG_KVM is not set +# CONFIG_LANCE is not set +CONFIG_LAPB=m +# CONFIG_LBD is not set +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +# CONFIG_LIBERTAS is not set +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_LNE390 is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_LSF is not set +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +# CONFIG_M386 is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MACHZ_WDT is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCA is not set +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +# CONFIG_MD is not set +# CONFIG_MDA_CONSOLE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +# CONFIG_MINIX_FS is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MLX4_CORE is not set +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_MOXA_SMARTIO_NEW is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSI_LAPTOP is not set +CONFIG_MSS=m +CONFIG_MSS_BLOCK=m +CONFIG_MSS_SDHCI=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWAVE is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NCP_FS is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_SECMARK=y +# CONFIG_NETXEN_NIC is not set +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +# CONFIG_NET_FC is not set +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +# CONFIG_NET_ISA is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PKTGEN=m +# CONFIG_NET_POCKET is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_NET_SB1000 is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_VENDOR_SMC is not set +CONFIG_NEW_LEDS=y +# CONFIG_NFSD is not set +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +CONFIG_NR_QUICK=1 +# CONFIG_NS83820 is not set +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NVRAM=m +# CONFIG_N_HDLC is not set +# CONFIG_OCFS2_FS is not set +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PARAVIRT is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARTITION_ADVANCED is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC8736x_GPIO=m +# CONFIG_PC87413_WDT is not set +# CONFIG_PCCARD is not set +CONFIG_PCI=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCIPCWATCHDOG is not set +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_MMCONFIG=y +# CONFIG_PCI_MSI is not set +# CONFIG_PCNET32 is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHONE is not set +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +# CONFIG_PLIP is not set +CONFIG_PLIST=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +# CONFIG_PM_LEGACY is not set +CONFIG_PM_STD_PARTITION="" +# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNPBIOS is not set +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +# CONFIG_PPDEV is not set +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_PRINTER is not set +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +# CONFIG_QLA3XXX is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +# CONFIG_R3964 is not set +# CONFIG_R8169 is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_FS is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_RIO is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +# CONFIG_S2IO is not set +CONFIG_SATA_AHCI=m +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_SC92031 is not set +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +CONFIG_SCSI=m +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_SCSI_INIA100=m +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_LPFC is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PPA is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_SEAGATE is not set +# CONFIG_SCSI_SIM710 is not set +CONFIG_SCSI_SPI_ATTRS=m +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_T128 is not set +CONFIG_SCSI_TGT=m +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +# CONFIG_SCx200 is not set +CONFIG_SCx200_ACB=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +# CONFIG_SGI_IOC4 is not set +# CONFIG_SHAPER is not set +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SK98LIN is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SLAB is not set +CONFIG_SLHC=m +# CONFIG_SLIP is not set +# CONFIG_SLOB is not set +CONFIG_SLUB=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +# CONFIG_SMSC37B787_WDT is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_AC97_POWER_SAVE is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ADLIB is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_DUMMY is not set +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +CONFIG_SND_HWDEP=m +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIO is not set +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_MIRO is not set +# CONFIG_SND_MIXART is not set +CONFIG_SND_MIXER_OSS=m +# CONFIG_SND_MONA is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MTS64 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_PORTMAN2X4 is not set +CONFIG_SND_RAWMIDI=m +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +CONFIG_SND_RTCTIMER=m +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SBAWE is not set +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SOC is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_SSCAPE is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_SOFT_WATCHDOG=m +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +CONFIG_SOUND=m +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPECIALIX is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSFDC=m +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STALDRV is not set +CONFIG_STANDALONE=y +CONFIG_STOP_MACHINE=y +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUSPEND_SMP=y +CONFIG_SWAP=y +# CONFIG_SX is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEKRAM_DONGLE=m +# CONFIG_TELCLOCK is not set +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +# CONFIG_THINKPAD_ACPI is not set +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +# CONFIG_TIGON3 is not set +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +# CONFIG_TIPAR is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TLAN is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TOIM3232_DONGLE is not set +# CONFIG_TOSHIBA is not set +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +# CONFIG_TR is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_FS is not set +# CONFIG_UID16 is not set +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +# CONFIG_USBPCWATCHDOG is not set +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +# CONFIG_USB_U132_HCD is not set +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_VGASTATE is not set +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_SELECT=y +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +# CONFIG_VLAN_8021Q is not set +CONFIG_VLSI_FIR=m +CONFIG_VM86=y +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VXFS_FS is not set +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83697HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_WAN is not set +CONFIG_WAN_ROUTER=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WRAPPER_PRINT=y +CONFIG_X25=m +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_ALIGNMENT_16=y +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CMPXCHG=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_F00F_BUG=y +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_GX_SUSPMOD is not set +CONFIG_X86_HT=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +# CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_LONGRUN is not set +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_MODEL=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_P4_CLOCKMOD is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +# CONFIG_X86_POWERNOW_K6 is not set +# CONFIG_X86_POWERNOW_K7 is not set +# CONFIG_X86_POWERNOW_K8 is not set +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +# CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI is not set +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +# CONFIG_X86_SPEEDSTEP_SMI is not set +# CONFIG_X86_SUMMIT is not set +CONFIG_X86_TRAMPOLINE=y +# CONFIG_X86_VISWS is not set +# CONFIG_X86_VOYAGER is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_FS is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_ZD1211RW is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-source-2.6.22-2.6.22.orig/debian/config/sparc/config +++ linux-source-2.6.22-2.6.22/debian/config/sparc/config @@ -0,0 +1,1810 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ACORN_PARTITION is not set +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADAPTEC_STARFIRE_NAPI=y +# CONFIG_ADFS_FS is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_AMIGA_PARTITION is not set +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_ARCNET is not set +CONFIG_ARPD=y +CONFIG_ATA=m +CONFIG_ATALK=m +# CONFIG_ATARI_PARTITION is not set +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +# CONFIG_ATM is not set +CONFIG_ATMEL=m +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_ARCH=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +# CONFIG_B44 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BBC_I2C=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +# CONFIG_BINFMT_AOUT32 is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_ELF32=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_AEC62XX is not set +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_IDESCSI is not set +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BONDING=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_BT is not set +CONFIG_BUG=y +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPAT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +# CONFIG_CPU_FREQ is not set +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +# CONFIG_DE2104X is not set +# CONFIG_DE4X5 is not set +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BOOTMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DCFLUSH is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_DECNET_ROUTER=y +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +# CONFIG_DEFXX is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +# CONFIG_DEV_APPLETALK is not set +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY7SEG=m +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_DM9102 is not set +CONFIG_DMA_ENGINE=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DRM=y +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DVB_CORE is not set +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +# CONFIG_EEPRO100 is not set +# CONFIG_EFI_PARTITION is not set +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_ENVCTRL=m +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +CONFIG_FB_ARK=m +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_ATY=y +CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +# CONFIG_FB_BW2 is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CG14 is not set +# CONFIG_FB_CG3 is not set +CONFIG_FB_CG6=y +# CONFIG_FB_CIRRUS is not set +CONFIG_FB_DDC=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_FFB=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LEO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_P9100 is not set +CONFIG_FB_PM2=y +# CONFIG_FB_PM2_FIFO_DISCONNECT is not set +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RIVA is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SBUS=y +# CONFIG_FB_SIS is not set +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TCX is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +CONFIG_FB_VT8623=m +CONFIG_FB_XVR2500=y +CONFIG_FB_XVR500=y +CONFIG_FC4=m +CONFIG_FC4_SOC=m +CONFIG_FC4_SOCAL=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN12x22 is not set +CONFIG_FONT_SUN8x16=y +# CONFIG_FORCEDETH is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_TIME=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +CONFIG_HAPPYMEAL=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +# CONFIG_HP100 is not set +CONFIG_HPFS_FS=m +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_SIZE_4MB=y +# CONFIG_HUGETLB_PAGE_SIZE_512K is not set +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_ISA=m +# CONFIG_I2C_NFORCE2 is not set +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +# CONFIG_I2O_CONFIG is not set +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_ONLYDISK=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +# CONFIG_INPUT_EVBUG is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_SPARCSPKR=y +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_RARP=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +# CONFIG_IRDA is not set +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_IXGB=m +CONFIG_IXGB_NAPI=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_FS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=y +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +# CONFIG_LAPB is not set +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +# CONFIG_LKDTM is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC_PARTITION is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MII=m +CONFIG_MINIX_FS=m +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +# CONFIG_MTD is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI_SBUS=m +CONFIG_NATSEMI=m +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +CONFIG_NCPFS_NFS_NS=y +# CONFIG_NCPFS_NLS is not set +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_STRONG is not set +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +# CONFIG_NET_IPGRE is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +CONFIG_NO_HZ=y +CONFIG_NR_QUICK=1 +CONFIG_NS83820=m +# CONFIG_NTFS_FS is not set +CONFIG_N_HDLC=m +CONFIG_OBP_FLASH=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +# CONFIG_OSF_PARTITION is not set +# CONFIG_OSS_OBSOLETE is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_PARIDE is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SUNBPP=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +CONFIG_PCI=y +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_HERMES is not set +# CONFIG_PCI_MSI is not set +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +# CONFIG_PDC202XX_BURST is not set +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +# CONFIG_PHONE is not set +CONFIG_PHYLIB=m +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +# CONFIG_PNPACPI is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROFILING is not set +CONFIG_PROM_CONSOLE=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +# CONFIG_QNX4FS_FS is not set +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_R3964=m +# CONFIG_R8169 is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +CONFIG_S2IO_NAPI=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBUS=y +CONFIG_SBUSCHAR=y +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_FCAL=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PLUTO=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGICPTI=m +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SUNESP=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +# CONFIG_SENSORS_ADM1031 is not set +CONFIG_SENSORS_ADM9240=m +# CONFIG_SENSORS_ASB100 is not set +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM is not set +CONFIG_SENSORS_F71805F=m +# CONFIG_SENSORS_FSCHER is not set +CONFIG_SENSORS_FSCPOS=m +# CONFIG_SENSORS_GL518SM is not set +CONFIG_SENSORS_GL520SM=m +# CONFIG_SENSORS_IT87 is not set +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +CONFIG_SENSORS_LM87=m +# CONFIG_SENSORS_LM90 is not set +CONFIG_SENSORS_LM92=m +# CONFIG_SENSORS_MAX1619 is not set +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +# CONFIG_SENSORS_VIA686A is not set +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83781D is not set +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +# CONFIG_SENSORS_W83L785TS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIAL_SUNCORE=y +CONFIG_SERIAL_SUNHV=y +CONFIG_SERIAL_SUNSAB=y +CONFIG_SERIAL_SUNSAB_CONSOLE=y +CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y +CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_PCIPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SGI_IOC4=m +# CONFIG_SGI_PARTITION is not set +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_MODE_SLIP6 is not set +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +# CONFIG_SND_ATIIXP is not set +CONFIG_SND_ATIIXP_MODEM=m +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_DUMMY is not set +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +# CONFIG_SND_MIXART is not set +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +# CONFIG_SND_MPU401 is not set +CONFIG_SND_MPU401_UART=m +# CONFIG_SND_MTPAV is not set +CONFIG_SND_MTS64=m +# CONFIG_SND_NM256 is not set +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_RTCTIMER is not set +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_SOC=m +# CONFIG_SND_SONICVIBES is not set +CONFIG_SND_SUN_AMD7930=m +CONFIG_SND_SUN_CS4231=m +CONFIG_SND_SUN_DBRI=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_USB_AUDIO is not set +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VIA82XX is not set +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SOLARIS_EMUL=m +# CONFIG_SOLARIS_X86_PARTITION is not set +CONFIG_SOUND=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_TRIDENT is not set +CONFIG_SPARC=y +CONFIG_SPARC32_COMPAT=y +CONFIG_SPARC64=y +# CONFIG_SPARC64_PAGE_SIZE_4MB is not set +# CONFIG_SPARC64_PAGE_SIZE_512KB is not set +# CONFIG_SPARC64_PAGE_SIZE_64KB is not set +CONFIG_SPARC64_PAGE_SIZE_8KB=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPECIALIX is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_DEBUG is not set +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STRIP=m +CONFIG_SUNBMAC=m +CONFIG_SUNDANCE=m +CONFIG_SUNDANCE_MMIO=y +CONFIG_SUNGEM=y +CONFIG_SUNLANCE=m +CONFIG_SUNQE=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUNVDC=m +CONFIG_SUNVNET=m +CONFIG_SUN_AUXIO=y +# CONFIG_SUN_BPP is not set +CONFIG_SUN_IO=y +CONFIG_SUN_LDOMS=y +CONFIG_SUN_MOSTEK_RTC=y +CONFIG_SUN_OPENPROMFS=m +CONFIG_SUN_OPENPROMIO=y +CONFIG_SUN_PARTITION=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPAR=m +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TR is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_NAPI=y +CONFIG_TULIP_NAPI_HW_MITIGATION=y +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_ULI526X=m +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +# CONFIG_USB_ACM is not set +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_AUERSWALD is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +# CONFIG_USB_PHIDGETSERVO is not set +CONFIG_USB_PRINTER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +# CONFIG_USB_SERIAL is not set +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +# CONFIG_USB_USS720 is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_ZR364XX=m +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +CONFIG_VGASTATE=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +# CONFIG_VIDEO_CX88 is not set +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +# CONFIG_VIDEO_SAA5249 is not set +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVISION=m +# CONFIG_VIDEO_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VXFS_FS is not set +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WINBOND_840=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_SECURITY is not set +CONFIG_YELLOWFIN=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA_FLAG=0 --- linux-source-2.6.22-2.6.22.orig/debian/config/sparc/config.sparc64 +++ linux-source-2.6.22-2.6.22/debian/config/sparc/config.sparc64 @@ -0,0 +1,10 @@ +# +# Config options for config.sparc64 automatically generated by splitconfig.pl +# +CONFIG_BROKEN_ON_SMP=y +CONFIG_ISTALLION=m +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_RIO is not set +CONFIG_RISCOM8=m +# CONFIG_SMP is not set +CONFIG_STALLION=m --- linux-source-2.6.22-2.6.22.orig/debian/config/sparc/config.sparc64-smp +++ linux-source-2.6.22-2.6.22/debian/config/sparc/config.sparc64-smp @@ -0,0 +1,15 @@ +# +# Config options for config.sparc64-smp automatically generated by splitconfig.pl +# +CONFIG_CPUSETS=y +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCK_KERNEL=y +CONFIG_NR_CPUS=256 +CONFIG_PATA_CMD640_PCI=m +# CONFIG_PREEMPT_BKL is not set +CONFIG_RIO=m +CONFIG_RIO_OLDPCI=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_SMP=y +CONFIG_STOP_MACHINE=y --- linux-source-2.6.22-2.6.22.orig/debian/config/amd64/config +++ linux-source-2.6.22-2.6.22/debian/config/amd64/config @@ -0,0 +1,2748 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_60XX_WDT=m +CONFIG_64BIT=y +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC97_BUS=m +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y +CONFIG_ACPI_SLEEP_PROC_SLEEP=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADVANTECH_WDT=m +# CONFIG_AEDSP16_MSS is not set +# CONFIG_AEDSP16_SBPRO is not set +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=m +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATL1=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_ARCH=y +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_B44=m +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD64X=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_OPTI621=m +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +CONFIG_BLK_DEV_TRM290=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BONDING=m +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_COMPAT=y +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DELL_RBU=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DE_AOC=y +CONFIG_DGRS=m +CONFIG_DIGIEPCA=m +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=m +CONFIG_EDAC=m +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +# CONFIG_EDD is not set +CONFIG_EEPRO100=m +CONFIG_EFI_PARTITION=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FARSYNC=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +# CONFIG_FB_ARC is not set +CONFIG_FB_ARK=m +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CFB_COPYAREA=m +CONFIG_FB_CFB_FILLRECT=m +CONFIG_FB_CFB_IMAGEBLIT=m +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_GEODE_GX_SET_FBSIZE is not set +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIPPI=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +# CONFIG_HPET_EMULATE_RTC is not set +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_INTEL=m +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +# CONFIG_IA32_AOUT is not set +CONFIG_IA32_EMULATION=y +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMOL=m +CONFIG_IBM_ASM=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_IOMMU=y +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPPP_FILTER=y +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_K8_NB=y +CONFIG_K8_NUMA=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_INTEL=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_LEDS=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MFD_SM501=m +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MIGRATION=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +# CONFIG_MSS is not set +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +CONFIG_MWAVE=m +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NE2K_PCI=m +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NIU is not set +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NODES_SHIFT=6 +# CONFIG_NORTEL_HERMES is not set +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_OSF_PARTITION=y +# CONFIG_OSS_OBSOLETE is not set +CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +CONFIG_PC300=m +# CONFIG_PC300TOO is not set +CONFIG_PC300_MLPPP=y +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDC202XX_BURST=y +CONFIG_PDC_ADMA=m +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_START=0x200000 +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_LEGACY=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SYSFS_DEPRECATED=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRISM54=m +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_PSS_MIXER=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_R3964=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_RIO is not set +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RTC=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0x0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_MC=y +CONFIG_SCSI=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHAPER=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +# CONFIG_SK98LIN is not set +CONFIG_SKFP=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_RTCTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +CONFIG_SOUND_AEDSP16=m +# CONFIG_SOUND_DMAP is not set +CONFIG_SOUND_MPU401=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_PAS is not set +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +# CONFIG_SOUND_SB is not set +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_TRIDENT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSFDC=m +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_STALDRV=y +CONFIG_STANDALONE=y +CONFIG_STOP_MACHINE=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND_SMP=y +CONFIG_SWAP=y +CONFIG_SWIOTLB=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPAR=m +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TR=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_SELECT=y +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLSI_FIR=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WDC_ALI15X3 is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_WRAPPER_PRINT is not set +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +CONFIG_X86_64=y +CONFIG_X86_64_ACPI_NUMA=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPUID=m +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_HT=y +CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MSR=m +# CONFIG_X86_P4_CLOCKMOD is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8_ACPI=y +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_SPEEDSTEP_LIB is not set +CONFIG_X86_TSC=y +# CONFIG_X86_VSMP is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XFS_SECURITY=y +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-source-2.6.22-2.6.22.orig/debian/config/amd64/config.generic +++ linux-source-2.6.22-2.6.22/debian/config/amd64/config.generic @@ -0,0 +1,18 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_IPC_NS is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_SCHED_SMT is not set +# CONFIG_UTS_NS is not set --- linux-source-2.6.22-2.6.22.orig/debian/config/amd64/config.server +++ linux-source-2.6.22-2.6.22/debian/config/amd64/config.server @@ -0,0 +1,19 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_IPC_NS=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +CONFIG_NETLABEL=y +CONFIG_NR_CPUS=64 +# CONFIG_PREEMPT_BKL is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_SCHED_SMT=y +CONFIG_UTS_NS=y --- linux-source-2.6.22-2.6.22.orig/debian/config/hppa/config +++ linux-source-2.6.22-2.6.22/debian/config/hppa/config @@ -0,0 +1,1177 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_53C700_LE_ON_BE=y +CONFIG_ACENIC=m +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_ANON_INODES=y +# CONFIG_APPLICOM is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_ARCNET is not set +# CONFIG_ARPD is not set +CONFIG_ATA=m +# CONFIG_ATALK is not set +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_ATA_PIIX=m +# CONFIG_ATM is not set +# CONFIG_ATMEL is not set +CONFIG_AUDIT=y +CONFIG_AUDIT_GENERIC=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +# CONFIG_BLK_CPQ_CISS_DA is not set +CONFIG_BLK_CPQ_DA=m +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=m +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_DM=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_NS87415=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_TC86C001=m +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLOCK=y +# CONFIG_BONDING is not set +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_BT is not set +CONFIG_BUG=y +CONFIG_CARDBUS=y +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +# CONFIG_CD_NO_IDESCSI is not set +CONFIG_CFG80211=m +CONFIG_CHASSIS_LCD_LED=y +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +# CONFIG_CODA_FS is not set +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +# CONFIG_DE4X5 is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEVPORT=y +# CONFIG_DM9102 is not set +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_MIRROR=m +# CONFIG_DM_MULTIPATH is not set +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +# CONFIG_DRM is not set +# CONFIG_DTLK is not set +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=160 +CONFIG_DUMMY_CONSOLE_ROWS=64 +# CONFIG_DVB_CORE is not set +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +# CONFIG_ECONET is not set +# CONFIG_EFS_FS is not set +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +# CONFIG_FDDI is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FORCED_INLINING=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_TIME=y +CONFIG_GEN_RTC=y +CONFIG_GEN_RTC_X=y +CONFIG_GSC=y +CONFIG_GSC_DINO=y +CONFIG_GSC_LASI=y +CONFIG_GSC_WAX=y +# CONFIG_HAMRADIO is not set +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +# CONFIG_HIPPI is not set +CONFIG_HOTPLUG=y +# CONFIG_HOTPLUG_PCI is not set +CONFIG_HP100=m +# CONFIG_HPFS_FS is not set +CONFIG_HPPB=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_CONSOLE=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_I2C is not set +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +# CONFIG_INFINIBAND is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_IOMMU_CCIO=y +CONFIG_IOMMU_SBA=y +CONFIG_IOSAPIC=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IPC_NS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +# CONFIG_IPX is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_RARP is not set +CONFIG_IP_SCTP=m +# CONFIG_IP_VS is not set +# CONFIG_IRDA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_ISA=y +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KEYS=y +CONFIG_KMOD=y +# CONFIG_LAPB is not set +CONFIG_LASI_82596=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD_V4=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LXT_PHY=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MD=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +CONFIG_MII=m +# CONFIG_MINIX_FS is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MMC is not set +CONFIG_MMU=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +# CONFIG_MSS is not set +# CONFIG_MTD is not set +# CONFIG_NCP_FS is not set +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +# CONFIG_NET_FC is not set +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POCKET is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NFSD=m +CONFIG_NFSD_TCP=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +# CONFIG_NI52 is not set +# CONFIG_NIU is not set +CONFIG_NLS=y +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# 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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_2 is not set +# 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_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_NORTEL_HERMES is not set +# CONFIG_OCFS2_FS is not set +CONFIG_OPROFILE=m +# CONFIG_PA7100LC is not set +# CONFIG_PA7200 is not set +# CONFIG_PA7300LC is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_PARIDE is not set +CONFIG_PARISC=y +# CONFIG_PARISC_PAGE_SIZE_16KB is not set +CONFIG_PARISC_PAGE_SIZE_4KB=y +# CONFIG_PARISC_PAGE_SIZE_64KB is not set +CONFIG_PARPORT=m +# CONFIG_PARPORT_1284 is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_GSC=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARTITION_ADVANCED is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_PDC_OLD is not set +CONFIG_PATA_QDI=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TRIFLEX=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_HERMES is not set +CONFIG_PCI_LBA=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_PD6729=m +CONFIG_PDC_ADMA=m +CONFIG_PDC_CHASSIS=y +CONFIG_PDC_CHASSIS_WARN=y +CONFIG_PDC_STABLE=y +CONFIG_PHANTOM=m +# CONFIG_PHONE is not set +CONFIG_PHYLIB=m +CONFIG_PLIP=m +CONFIG_PLIST=y +# CONFIG_PLX_HERMES is not set +# CONFIG_PNP is not set +# CONFIG_PNPACPI is not set +CONFIG_POSIX_MQUEUE=y +# CONFIG_PPDEV is not set +CONFIG_PPP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +# CONFIG_PRISM54 is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +# CONFIG_QNX4FS_FS is not set +CONFIG_QSEMI_PHY=m +# CONFIG_QUOTA is not set +# CONFIG_R3964 is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RELAY=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +# CONFIG_ROMFS_FS is not set +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_RXKAD=m +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_HPTIOP=m +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_IN2000 is not set +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LASI700=m +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PPA is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_PSI240I is not set +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_SIM710 is not set +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_SRP=m +CONFIG_SCSI_STEX=m +# CONFIG_SCSI_SYM53C416 is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_T128 is not set +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +CONFIG_SCSI_ZALON=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_SELINUX is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_GSC=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SGI_IOC4=m +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SK98LIN is not set +CONFIG_SLHC=m +# CONFIG_SLOB is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_SMC9194=m +CONFIG_SMSC_PHY=m +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_STACK_GROWSUP=y +CONFIG_STANDALONE=y +CONFIG_SUNGEM=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUPERIO=y +CONFIG_SWAP=y +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCG_TPM is not set +CONFIG_TCIC=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +# CONFIG_TINY_SHMEM is not set +# CONFIG_TIPAR is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +# CONFIG_TMD_HERMES is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TR is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_USB=m +# CONFIG_USB_ACM is not set +CONFIG_USB_ADUTUX=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_AUERSWALD is not set +CONFIG_USB_BERRY_CHARGE=m +# CONFIG_USB_CATC is not set +CONFIG_USB_CYPRESS_CY7C63=m +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_DABUSB=m +CONFIG_USB_DEBUG=y +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +# CONFIG_USB_ET61X251 is not set +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_IDMOUSE is not set +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_KBD=m +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_LCD is not set +CONFIG_USB_LD=m +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LIBUSUAL=y +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SISUSBVGA is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +# CONFIG_USB_SN9C102 is not set +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +CONFIG_USB_STORAGE_USBAT=y +# CONFIG_USB_STV680 is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USS720 is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_UTS_NS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BWQCAM is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_STRADIS is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_VIVI is not set +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_W1 is not set +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +CONFIG_WD80x3=m +# CONFIG_WINBOND_840 is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_XFS_FS=m +# CONFIG_XFS_RT is not set +# CONFIG_XFS_SECURITY is not set +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZONE_DMA_FLAG=0 --- linux-source-2.6.22-2.6.22.orig/debian/config/hppa/config.hppa64 +++ linux-source-2.6.22-2.6.22/debian/config/hppa/config.hppa64 @@ -0,0 +1,176 @@ +# +# Config options for config.hppa64 automatically generated by splitconfig.pl +# +CONFIG_64BIT=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_AC3200 is not set +CONFIG_ACENIC_OMIT_TIGON_I=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AGP is not set +# CONFIG_AIRO_CS is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APRICOT is not set +CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +# CONFIG_AT1700 is not set +# CONFIG_ATL1 is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_B44 is not set +# CONFIG_BCM43XX is not set +# CONFIG_BNX2 is not set +CONFIG_BROKEN_ON_SMP=y +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +CONFIG_COMPAT=y +# CONFIG_CRAMFS is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_DES=m +# CONFIG_CS89x0 is not set +CONFIG_DE2104X=m +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEPCA is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DGRS is not set +CONFIG_DISCONTIGMEM=y +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DL2K is not set +# CONFIG_DLM is not set +# CONFIG_DMA_ENGINE is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_EEPRO100 is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_EPIC100 is not set +# CONFIG_ES3210 is not set +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +# CONFIG_FB is not set +# CONFIG_FEALNX is not set +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FUSE_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_HAMACHI is not set +CONFIG_HID=y +# CONFIG_HOSTAP is not set +# CONFIG_HWMON is not set +# CONFIG_HW_RANDOM is not set +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_ISO9660_FS=y +# CONFIG_IXGB is not set +CONFIG_JBD=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_KS0108 is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_LNE390 is not set +CONFIG_LOCKD=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MFD_SM501 is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_NEW_LEDS is not set +CONFIG_NFS_FS=m +# CONFIG_NI5010 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NODES_SHIFT=3 +# CONFIG_NS83820 is not set +# CONFIG_NTFS_FS is not set +CONFIG_PA20=y +# CONFIG_PA7000 is not set +CONFIG_PA8X00=y +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +# CONFIG_PPPOE is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPP_MULTILINK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREFETCH=y +# CONFIG_PRINTER is not set +# CONFIG_PRINTK_TIME is not set +# CONFIG_QLA3XXX is not set +# CONFIG_R8169 is not set +CONFIG_RAW_DRIVER=y +# CONFIG_REISERFS_FS is not set +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RTC_CLASS is not set +# CONFIG_S2IO is not set +# CONFIG_SC92031 is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_8250_NR_UARTS=17 +CONFIG_SERIAL_MUX=y +CONFIG_SERIAL_MUX_CONSOLE=y +# CONFIG_SERIO is not set +# CONFIG_SHAPER is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_SLAB=y +# CONFIG_SLIP is not set +# CONFIG_SLUB is not set +# CONFIG_SMP is not set +# CONFIG_SOUND is not set +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_STI_CONSOLE is not set +# CONFIG_SUNDANCE is not set +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SYNCLINK_CS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_TULIP=y +CONFIG_TULIP_MMIO=y +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_ULI526X is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_VXFS_FS is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_INFLATE=m --- linux-source-2.6.22-2.6.22.orig/debian/config/hppa/config.hppa32 +++ linux-source-2.6.22-2.6.22/debian/config/hppa/config.hppa32 @@ -0,0 +1,458 @@ +# +# Config options for config.hppa32 automatically generated by splitconfig.pl +# +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_AC3200=m +CONFIG_AC97_BUS=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_AGP=m +CONFIG_AIRO_CS=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_AMD8111_ETH=m +CONFIG_APRICOT=m +# CONFIG_ARLAN is not set +CONFIG_AT1700=m +CONFIG_ATL1=m +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_B44=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BNX2=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_CPUSETS=y +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_DES=y +CONFIG_CS89x0=m +# CONFIG_DE2104X is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_RWLOCK is not set +CONFIG_DEPCA=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DGRS=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DL2K=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DMA_ENGINE=y +CONFIG_E2100=m +CONFIG_ECRYPT_FS=m +CONFIG_EEPRO100=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPIC100=m +CONFIG_ES3210=m +CONFIG_ETH16I=m +CONFIG_EWRK3=m +CONFIG_EXT2_FS=m +CONFIG_EXT3_FS=m +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +CONFIG_FB_ARK=m +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_PM3=m +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_S3=m +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +CONFIG_FB_SM501=m +CONFIG_FB_STI=y +CONFIG_FB_SVGALIB=m +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +CONFIG_FB_VT8623=m +CONFIG_FEALNX=m +CONFIG_FIRMWARE_EDID=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FUSE_FS=m +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_HAMACHI=m +CONFIG_HID=m +CONFIG_HIL_MLC=m +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG_CPU=y +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +# CONFIG_HPUX is not set +CONFIG_HP_SDC=m +CONFIG_HP_SDC_RTC=m +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_ISO9660_FS=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_JBD=m +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_ATKBD_HP_KEYCODES is not set +CONFIG_KEYBOARD_HIL=m +CONFIG_KEYBOARD_HIL_OLD=m +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_STOWAWAY=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +# CONFIG_LBD is not set +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LNE390=m +CONFIG_LOCKD=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LP486E=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_LSF is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MFD_SM501=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_HIL=m +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MYRI10GE=m +CONFIG_NATSEMI=m +CONFIG_NE2000=m +CONFIG_NE2K_PCI=m +CONFIG_NE3210=m +CONFIG_NETCONSOLE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETXEN_NIC=m +CONFIG_NET_DMA=y +CONFIG_NET_ISA=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NEW_LEDS=y +CONFIG_NFS_FS=y +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NR_CPUS=32 +CONFIG_NS83820=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +# CONFIG_OSS_OBSOLETE is not set +CONFIG_PA11=y +CONFIG_PA7000=y +# CONFIG_PA8X00 is not set +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PDC_CONSOLE=y +CONFIG_PPPOE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PRINTER=m +CONFIG_PRINTK_TIME=y +CONFIG_QLA3XXX=m +CONFIG_QUOTACTL=y +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +# CONFIG_RAW_DRIVER is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_ROOT_NFS=y +CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_SC92031=m +# CONFIG_SCSI_AHA152X is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_NSP32=m +CONFIG_SEEQ8005=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_NR_UARTS=48 +# CONFIG_SERIAL_MUX is not set +CONFIG_SERIO=y +CONFIG_SERIO_GSCPS2=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_SERPORT is not set +CONFIG_SHAPER=m +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SLAB is not set +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_MODE_SLIP6 is not set +CONFIG_SLIP_SMART=y +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMP=y +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALI5451 is not set +CONFIG_SND_ALS300=m +# CONFIG_SND_ATIIXP is not set +CONFIG_SND_ATIIXP_MODEM=m +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +# CONFIG_SND_EMU10K1 is not set +CONFIG_SND_EMU10K1X=m +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HARMONY=m +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +CONFIG_SND_HDSPM=m +CONFIG_SND_HWDEP=m +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +# CONFIG_SND_MAESTRO3 is not set +CONFIG_SND_MIA=m +# CONFIG_SND_MIXART is not set +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +# CONFIG_SND_MPU401 is not set +CONFIG_SND_MPU401_UART=m +# CONFIG_SND_MTPAV is not set +CONFIG_SND_MTS64=m +# CONFIG_SND_NM256 is not set +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_SEQ_DUMMY is not set +# CONFIG_SND_SERIAL_U16550 is not set +CONFIG_SND_SOC=m +# CONFIG_SND_SONICVIBES is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_USB_AUDIO is not set +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_VX222 is not set +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +# CONFIG_SND_YMFPCI is not set +CONFIG_SOUND=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_TRIDENT is not set +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_STI_CONSOLE=y +CONFIG_STOP_MACHINE=y +# CONFIG_STRIP is not set +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SYNCLINK_CS=m +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TIMER_STATS=y +CONFIG_TIME_LOW_RES=y +CONFIG_TLAN=m +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_UFS_FS is not set +CONFIG_ULI526X=m +CONFIG_UNUSED_SYMBOLS=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_VGASTATE=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_VIA_VELOCITY=m +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +# CONFIG_WAVELAN is not set +CONFIG_WLAN_PRE80211=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_YELLOWFIN=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_INFLATE=y --- linux-source-2.6.22-2.6.22.orig/debian/control.stub.in +++ linux-source-2.6.22-2.6.22/debian/control.stub.in @@ -0,0 +1,83 @@ +Source: linux-source-PKGVER +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-PKGVER +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version PKGVER with Ubuntu patches + This package provides the source code for the Linux kernel version PKGVER. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-PKGVER/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-PKGVER +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version PKGVER + This package provides the various readme's in the PKGVER kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-PKGVER/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-PKGVER-ABINUM +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version PKGVER + This package provides kernel header files for version PKGVER, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1) +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6) +Provides: linux-kernel-headers +Conflicts: linux-kernel-headers +Replaces: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. --- linux-source-2.6.22-2.6.22.orig/debian/rules +++ linux-source-2.6.22-2.6.22/debian/rules @@ -0,0 +1,115 @@ +#!/usr/bin/make -f +# +# debian/rules for Ubuntu linux-source +# +# Use this however you want, just give credit where credit is due. +# +# Copyright (c) 2007 Ben Collins +# + +# This is the debhelper compatability version to use. +export DH_COMPAT=4 +export LC_ALL=C +export SHELL=/bin/bash -e + +# Common variables for all architectures +include debian/rules.d/0-common-vars.mk + +# Pill in some arch specific stuff +include debian/rules.d/$(arch).mk + +# Maintainer targets +include debian/rules.d/1-maintainer.mk + +# Debian Build System targets +binary: binary-indep binary-arch + +build: build-arch build-indep + +clean: debian/control + dh_testdir + dh_testroot + dh_clean + + # d-i stuff + rm -rf modules kernel-versions package-list + rm -rf debian/d-i-$(arch) + + # normal build junk + rm -rf debian/abi/$(release)-$(revision) + rm -rf $(builddir) + rm -f $(stampdir)/stamp-* + + # This gets rid of the d-i packages in control + cp -f debian/control.stub debian/control + +# Builds the image, arch headers and debug packages +include debian/rules.d/2-binary-arch.mk + +# Rules for building the udebs (debian-installer) +include debian/rules.d/5-udebs.mk + +# Builds the source, doc and linux-headers indep packages +include debian/rules.d/3-binary-indep.mk + +# Various checks to be performed on builds +include debian/rules.d/4-checks.mk + +# Custom binary images (universe/unsupported) +include debian/rules.d/6-binary-custom.mk \ + $(patsubst %,debian/binary-custom.d/%/rules,$(custom_flavours)) + +# Misc stuff +debian/control.stub: debian/d-i/kernel-versions.in \ + debian/scripts/control-create \ + debian/control.stub.in \ + debian/changelog \ + $(wildcard debian/control.d/*) \ + $(patsubst %,debian/binary-custom.d/%/vars,$(all_custom_flavours)) + for i in debian/d-i/kernel-versions.in debian/control.stub.in; do \ + new=`echo $$i | sed 's/\.in$$//'`; \ + cat $$i | sed -e 's/PKGVER/$(pkgversion)/g' -e 's/ABINUM/$(abinum)/g' > \ + $$new; \ + done + flavours="$(wildcard debian/control.d/vars.*) $(patsubst %,debian/binary-custom.d/%/vars,$(all_custom_flavours))";\ + for i in $$flavours; do \ + $(SHELL) debian/scripts/control-create $$i | \ + sed -e 's/PKGVER/$(pkgversion)/g' -e 's/ABINUM/$(abinum)/g' >>\ + debian/control.stub; \ + done + cp debian/control.stub debian/control + +.PHONY: debian/control +debian/control: debian/control.stub + rm -rf modules kernel-versions package-list + mkdir -p modules/$(arch)/ + cp debian/d-i/modules/* modules/$(arch)/ + cp debian/d-i/package-list debian/d-i/kernel-versions . + touch modules/$(arch)/kernel-image + + # Per flavour module lists + flavour_modules=`ls debian/d-i/modules.$(arch)-* 2>/dev/null` \ + || true; \ + if [ "$$flavour_modules" != "" ]; then \ + for flav in $$flavour_modules; do \ + name=`echo $$flav | sed 's/.*\/modules.$(arch)-//'`; \ + mkdir modules/$(arch)-$$name; \ + (cd debian/d-i/modules/; tar cf - `cat ../../../$$flav`) |\ + (cd modules/$(arch)-$$name/; tar xf -); \ + touch modules/$(arch)-$$name/kernel-image; \ + done; \ + fi + + # Remove unwanted stuff + if [ -r "debian/d-i/exclude-modules.$(arch)" ]; then \ + (cat debian/d-i/exclude-modules.$(arch); \ + ls modules/$(arch)/) | sort | uniq -d | \ + (cd modules/$(arch)/; xargs rm -f); \ + fi + + if [ ! -d modules/$(build_arch) ]; then \ + mkdir -p modules/$(build_arch); \ + cp modules/$(arch)/* modules/$(build_arch); \ + fi + + kernel-wedge gen-control > debian/control --- linux-source-2.6.22-2.6.22.orig/debian/scripts/abi-check +++ linux-source-2.6.22-2.6.22/debian/scripts/abi-check @@ -0,0 +1,44 @@ +#!/bin/bash -e + +flavour="$1" +prev_abinum="$2" +abinum="$3" +prev_abidir="$4" +abidir="$5" +skipabi="$6" + +echo -n "Checking ABI for $flavour..." + +if [ -f "$prev_abidir/ignore" -o -f "$prev_abidir/$flavour.ignore" -o -n "$skipabi" ]; then + echo "explicitly asked to ignore ABI (probably not good)" + exit +fi + +if [ "$prev_abinum" = "0" -o "$prev_abinum" != "$abinum" ]; then + echo "different ABI numbers, no check needed." + exit +fi + +if [ ! -f "$abidir/$flavour" -o ! -f "$prev_abidir/$flavour" ]; then + echo "previous or current ABI file missing!" + echo " $abidir/$flavour" + echo " $prev_abidir/$flavour" + exit 1 +fi + +if [ "`diff -u $prev_abidir/$flavour $abidir/$flavour | grep ^-[^-] | wc -l`" != "0" ] +then + echo "check FAILED (nice one Tonto, go get the Lone Ranger)" + diff -u $prev_abidir/$flavour $abidir/$flavour + exit 1 +fi + +if [ "`diff -u $prev_abidir/$flavour $abidir/$flavour | grep ^+[^+] | wc -l`" != "0" ] +then + echo "new symbols in ABI (continuing reluctantly)" + diff -u $prev_abidir/$flavour $abidir/$flavour || true + exit +fi + +echo "check PASSED (good job, you saved yourself some work)" +exit --- linux-source-2.6.22-2.6.22.orig/debian/scripts/module-check +++ linux-source-2.6.22-2.6.22/debian/scripts/module-check @@ -0,0 +1,115 @@ +#!/usr/bin/perl -w + +$flavour = shift; +$prev_abidir = shift; +$abidir = shift; +$skipmodule = shift; + +print "II: Checking modules for $flavour..."; + +if (-f "$prev_abidir/ignore.modules" + or -f "$prev_abidir/$flavour.ignore.modules") { + print "explicitly ignoring modules\n"; + exit(0); +} + +if (not -f "$abidir/$flavour.modules" or not -f + "$prev_abidir/$flavour.modules") { + print "previous or current modules file missing!\n"; + print " $abidir/$flavour.modules\n"; + print " $prev_abidir/$flavour.modules\n"; + exit(1); +} + +print "\n"; + +my %modules; +my %modules_ignore; +my $missing = 0; +my $new = 0; +my $errors = 0; + +# See if we have any ignores +if (-f "$prev_abidir/../modules.ignore") { + my $ignore = 0; + open(IGNORE, "< $prev_abidir/../modules.ignore") or + die "Could not open $prev_abidir/../modules.ignore"; + print " reading modules to ignore..."; + while () { + chomp; + $modules_ignore{$_} = 1; + $ignore++; + } + close(IGNORE); + print "read $ignore modules.\n"; +} + +# Read new modules first +print " reading new modules..."; +$new_count = 0; +open(NEW, "< $abidir/$flavour.modules") or + die "Could not open $abidir/$flavour.modules"; +while () { + chomp; + $modules{$_} = 1; + $new_count++; +} +close(NEW); +print "read $new_count modules.\n"; + +# Now the old modules, checking for missing ones +print " reading old modules..."; +$old_count = 0; +open(OLD, "< $prev_abidir/$flavour.modules") or + die "Could not open $prev_abidir/$flavour.modules"; +while () { + chomp; + if (not defined($modules{$_})) { + print "\n" if not $missing; + $missing++; + if (not defined($modules_ignore{$_})) { + print " MISS: $_\n"; + $errors++; + } else { + print " MISS: $_ (ignored)\n"; + } + } else { + $modules{$_}++; + } + $old_count++; +} +close(OLD); +# Check for new modules +foreach $mod (keys(%modules)) { + if ($modules{$mod} < 2) { + print "\n" if not $missing and not $new; + print " NEW : $mod\n"; + $new++; + } +} +if ($new or $missing) { + print " read $old_count modules : new($new) missing($missing)\n"; +} else { + print "read $old_count modules.\n"; +} + + +# Let's see where we stand... +if ($errors) { + if (defined($skipmodule)) { + print "WW: Explicitly asked to ignore failures (probably not good)\n"; + } else { + print "EE: Missing modules (start begging for mercy)\n"; + exit 1 + } +} + +if ($new) { + print "II: New modules (you've been busy, wipe the poop off your nose)\n"; +} else { + print "II: No new modules (hope you're happy, slacker)\n"; +} + +print "II: Done\n"; + +exit(0); --- linux-source-2.6.22-2.6.22.orig/debian/scripts/link-headers +++ linux-source-2.6.22-2.6.22/debian/scripts/link-headers @@ -0,0 +1,79 @@ +#!/bin/bash -e + +hdrdir="$1" +symdir="$2" +srcdir="$3" +build_arch="$4" +flavour="$5" + +echo "Symlinking and copying headers for $flavour..." + +# XXX Special case for ppc +if [ "$build_arch" = "powerpc" ]; then + install -d -m755 $hdrdir/arch/powerpc/include + ln -fsn ../../../include/asm-ppc $hdrdir/arch/powerpc/include/asm +fi + +excludes='( -path ./debian -prune -o -path ./.git ) -prune -o' + +# For custom builds, we have to take care of a few things. First, we want +# to check for files to symlink and copy in the srcdir, not the stock src. +# We compare against stock source, copying for files that aren't the same, +# and later symlinking for same files. +if [ -n "$srcdir" ]; then + ( + cd $srcdir + find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print + find ./include ./scripts -name .gitignore -prune -o -type f -print + ) | ( + while read file; do + if [ -e "$hdrdir/$file" ]; then + continue + fi + + # If the files are not the same, copy it + if ! cmp -s "$file" "$srcdir/$file"; then + echo $file + fi + done + ) | ( + cd $srcdir + cpio -pd --preserve-modification-time "$hdrdir" + ) +else + srcdir="." +fi + +( +cd $srcdir +find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print +find ./include ./scripts -name .gitignore -prune -o -type f -print +find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print +) | ( +while read file; do + dir=$file + lastdir=$file + + if [ -f "$hdrdir/$file" ]; then + continue + fi + + while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do + lastdir=$dir + dir=`dirname $dir` + done + # If the last item to exist is a symlink we assume all is good + if [ ! -L "$hdrdir/$dir" ]; then + # Turns things like "./foo" into "../" + deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`" + item="`echo -n $lastdir | sed -e 's/^\.\///'`" + ln -s $deref$symdir/$item $hdrdir/$item + fi +done +) + +exit --- linux-source-2.6.22-2.6.22.orig/debian/scripts/control-create +++ linux-source-2.6.22-2.6.22/debian/scripts/control-create @@ -0,0 +1,32 @@ +#!/bin/bash + +stub=debian/control.d/flavour-control.stub +dstub=debian/control.d/flavour-control-debug.stub +vars=$1 + +# Defaults +section_image=base +section_headers=devel + +. $vars + +flavour=$(basename $vars | sed 's/.*\.//') +# Custom is a little different +if [ "$flavour" = "vars" ]; then + flavour=$(basename `dirname $vars`) +fi + +if [ -n "$do_debug" ]; then + stub="$stub $dstub" +fi + +cat $stub | grep -v '^#' | sed \ + -e "s#FLAVOUR#$flavour#g" \ + -e "s#DESC#$desc#g" \ + -e "s#ARCH#$arch#g" \ + -e "s#SUPPORTED#$supported#g" \ + -e "s#TARGET#$target#g" \ + -e "s#BOOTLOADER#$bootloader#g" \ + -e "s#=PROVIDES=#$provides#g" \ + -e "s#SECTION_IMAGE#$section_image#g" \ + -e "s#SECTION_HEADERS#$section_headers#g" --- linux-source-2.6.22-2.6.22.orig/debian/scripts/misc/oldconfig +++ linux-source-2.6.22-2.6.22/debian/scripts/misc/oldconfig @@ -0,0 +1,66 @@ +#!/bin/bash + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + + +# One arg, and that's it. Just pass an architecture +if [ $# -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +arch="$1" + +case "$arch" in + sparc) kernarch="sparc64" ;; + amd64) kernarch="x86_64" ;; + hppa) kernarch="parisc" ;; + lpia) kernarch="i386" ;; + *) kernarch="$arch" ;; +esac + +confdir="`pwd`/debian/config/$arch" +bindir="`pwd`/debian/scripts/misc" + +# Make sure the architecture exists +if [ ! -d $confdir ]; then + echo "Could not find config directory for $arch" 1>&2 + exit 1 +fi + +echo "Processing $arch ($kernarch) ... " + +configs=$(cd $confdir && ls config.*) + +if [ -f $confdir/config ]; then + for config in $configs; do + case $config in + *) + cat $confdir/config >> $confdir/$config + ;; + esac + done + rm -f $confdir/config +fi + +test -d build || mkdir build +cd build +for config in $configs; do + echo "Running silentoldconfig for $config ... " + + cat $confdir/$config > .config + + make -C ../ O=`pwd` silentoldconfig ARCH=$kernarch + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-source-2.6.22-2.6.22.orig/debian/scripts/misc/insert-changes.pl +++ linux-source-2.6.22-2.6.22/debian/scripts/misc/insert-changes.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl -w + +system("make -s -f debian/rules printchanges > debian/changes"); + +open(CHANGELOG, "< debian/changelog") or die "Cannot open changelog"; +open(CHANGES, "< debian/changes") or die "Cannot open new changes"; +open(NEW, "> debian/changelog.new") or die "Cannot open new changelog"; + +$printed = 0; + +while () { + if (/^ CHANGELOG: /) { + next if $printed; + + while () { + print NEW; + } + + $printed = 1; + } else { + print NEW; + } +} + +close(NEW); +close(CHANGES); +close(CHANGELOG); + +rename("debian/changelog.new", "debian/changelog"); +unlink("debian/changes"); --- linux-source-2.6.22-2.6.22.orig/debian/scripts/misc/git-ubuntu-log +++ linux-source-2.6.22-2.6.22/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,210 @@ +#!/usr/bin/perl -w + +use strict; +use Text::Wrap; + +my $kernel_auth = "Upstream Kernel Changes"; + +my (%map, @reverts); +my $pstate = 1; +my $no_kern_log = 0; +my $print_shas = 0; +my $first_print = 1; + +while (@ARGV) { + my $opt = $ARGV[0]; + shift; + if ($opt eq "--no-kern-log") { + $no_kern_log = 1; + } elsif ($opt eq "--print-shas") { + $print_shas = 1; + } else { + print STDERR "Unknown options: $opt\n"; + exit(1); + } +} + +sub check_reverts($) { + my ($entry) = @_; + my $found = 0; + my ($check, @replace); + + foreach $check (reverse @reverts) { + my $desc = "Revert \"" . $entry->{'desc'} . "\""; + if ($check->{'desc'} = $desc) { + $found = 1; + } else { + push(@replace, \$check); + } + } + + @reverts = @replace; + + return $found; +} + +sub add_entry($) { + my ($entry) = @_; + my $key = $entry->{'author'}; + + # store description in array, in email->{desc list} map + if (exists $map{$key}) { + # grab ref + my $obj = $map{$key}; + + # add desc to array + push(@$obj, $entry); + } else { + # create new array, containing 1 item + my @arr = ($entry); + + # store ref to array + $map{$key} = \@arr; + } +} + +sub shortlog_entry($$$$) { + my ($name, $desc, $bug, $commit) = @_; + my $entry; + + $desc =~ s#/pub/scm/linux/kernel/git/#/.../#g; + $desc =~ s#\[PATCH\] ##g; + + $desc =~ s#^\s*##g; + $desc =~ s# *UBUNTU: ##g; + + $entry->{'desc'} = $desc; + $entry->{'bugno'} = $bug; + $entry->{'commit'} = $commit; + $entry->{'author'} = $name; + + if ($desc =~ /^Revert "/) { + push(@reverts, $entry); + return; + } + + return if &check_reverts($entry); + + add_entry($entry); +} + +# sort comparison function +sub by_name($$) { + my ($a, $b) = @_; + + uc($a) cmp uc($b); +} + +sub shortlog_output { + my ($obj, $key, $entry); + + foreach $key (sort by_name keys %map) { + next if $key eq $kernel_auth and $no_kern_log; + + print "\n" unless $first_print; + $first_print = 0; + + # output author + printf " [%s]\n\n", $key; + + # output author's 1-line summaries + $obj = $map{$key}; + foreach $entry (reverse @$obj) { + print wrap(" * ", " ", $entry->{'desc'}) . "\n"; + # For non upstream changes, add other info. + if ($key ne $kernel_auth) { + if ($print_shas) { + print " - GIT-SHA " . $entry->{'commit'} . + "\n"; + } + if (defined($entry->{'bugno'})) { + print " - LP: #" . + $entry->{'bugno'} . "\n"; + } + } + } + } +} + +sub changelog_input { + my ($author, $desc, $commit, $entry); + + while () { + # get commit + if ($pstate == 1) { + next unless /^commit (.*)/; + + $commit = $1; + + $pstate++; + } + + # get author and email + elsif ($pstate == 2) { + my ($email); + + next unless /^[Aa]uthor:?\s*(.*?)\s*<(.*)>/; + + $author = $1; + $email = $2; + $desc = undef; + + # cset author fixups + if (!$author) { + $author = $email; + } + $pstate++; + } + + # skip to blank line + elsif ($pstate == 3) { + next unless /^\s*$/; + $pstate++; + } + + # skip to non-blank line + elsif ($pstate == 4) { + next unless /^\s*?(.*)/; + my $ignore = 0; + my $bug = undef; + + # skip lines that are obviously not + # a 1-line cset description + next if /^\s*From: /; + + chomp; + $desc = $1; + + if ($desc =~ /^ *(Revert "|)UBUNTU:/) { + while () { + $ignore = 1 if /^ *Ignore: yes/i; + $bug = $2 if /^ *Bug: *(#|)(.*)/; + last if /^$/; + } + } else { + $author = $kernel_auth; + $ignore = 1 if $desc =~ /Merge /; + } + + if (!$ignore) { + &shortlog_entry($author, $desc, $bug, + $commit, 0); + } + + $pstate = 1; + } + + else { + die "invalid parse state $pstate"; + } + } + + foreach $entry (@reverts) { + add_entry($entry); + } +} + +&changelog_input; +&shortlog_output; + +exit(0); --- linux-source-2.6.22-2.6.22.orig/debian/scripts/misc/splitconfig.pl +++ linux-source-2.6.22-2.6.22/debian/scripts/misc/splitconfig.pl @@ -0,0 +1,110 @@ +#!/usr/bin/perl -w + +%configs = (); +%common = (); + +print "Reading config's ...\n"; + +opendir(DIR, "."); + +while (defined($config = readdir(DIR))) { + # Only config.* + next if $config !~ /^config\..*/; + # Nothing that is disabled, or remnant + next if $config =~ /.*\.(default|disabled|stub)$/; + # Server config's are standalone + #next if $config =~ /config.server-.*/; + + %{$configs{$config}} = (); + + print " processing $config ... "; + + open(CONFIG, "< $config"); + + while () { + /^#*\s*CONFIG_(\w+)[\s=](.*)$/ or next; + + ${$configs{$config}}{$1} = $2; + + $common{$1} = $2; + } + + close(CONFIG); + + print "done.\n"; +} + +closedir(DIR); + +print "\n"; + +print "Merging lists ... \n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + for $key (keys(%common)) { + next if not defined $common{$key}; + + # If we don't have the common option, then it isn't + # common. If we do have that option, it must have the same + # value (this is where the old split.py was broken). It + # also did the common check while it was parsing files, so + # that there were cases where a non-common option was in + # common anyway (ordering). + if (not defined($options{$key})) { + undef $common{$key}; + } elsif ($common{$key} ne $options{$key}) { + undef $common{$key}; + } + } + + print "done.\n"; +} + +print "\n"; + +print "Creating common config ... "; + +open(COMMON, "> config"); +print COMMON "#\n# Common config options automatically generated by splitconfig.pl\n#\n"; + +for $key (sort(keys(%common))) { + next if not defined $common{$key}; + + if ($common{$key} eq "is not set") { + print COMMON "# CONFIG_$key is not set\n"; + } else { + print COMMON "CONFIG_$key=$common{$key}\n"; + } +} +close(COMMON); + +print "done.\n\n"; + +print "Creating stub configs ...\n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + open(STUB, "> $config"); + print STUB "#\n# Config options for $config automatically generated by splitconfig.pl\n#\n"; + + for $key (sort(keys(%options))) { + next if defined $common{$key}; + + if ($options{$key} eq "is not set") { + print STUB "# CONFIG_$key is not set\n"; + } else { + print STUB "CONFIG_$key=$options{$key}\n"; + } + } + + close(STUB); + + print "done.\n"; +} --- linux-source-2.6.22-2.6.22.orig/debian/scripts/misc/getabis +++ linux-source-2.6.22-2.6.22/debian/scripts/misc/getabis @@ -0,0 +1,87 @@ +#!/bin/bash + +if [ "$#" != "2" ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +ver=$1 +revision=$2 +abi=$(echo $revision | awk -F. '{print $1}') + +verabi=$ver-$abi +verfull=$ver-$revision + +repo="http://archive.ubuntu.com/ubuntu/pool/main/l" +repo_ports="http://ports.ubuntu.com/ubuntu-ports/pool/main/l" +repo_uni="http://archive.ubuntu.com/ubuntu/pool/universe/l" + +WGET="wget --quiet -c" + +abidir="`pwd`/debian/abi/$verfull" +tmpdir="`pwd`/abi-tmp-$verfull" +origdir="`pwd`" + +test -d $tmpdir || mkdir $tmpdir + +getall() { + arch=$1 + shift + + mkdir -p $abidir/$arch + + for sub in $@; do + if [ -f $abidir/$arch/$sub ]; then + echo "Exists: $sub" + continue + fi + echo -n "Fetching $sub..." + filename=linux-image-${verabi}-${sub}_${verfull}_${arch}.deb + cd $tmpdir + if ! [ -f $filename ]; then + $WGET $repo/linux-source-$ver/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_ports/linux-source-$ver/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_uni/linux-source-$ver/$filename + fi + if [ "$?" = "0" ]; then + echo -n "extracting..." + dpkg-deb --extract $filename tmp + if [ -f tmp/boot/abi-* ]; then + mv tmp/boot/abi-* $abidir/$arch/$sub + else + echo -n "NO ABI FILE..." + fi + (cd tmp; find lib/modules/$verabi-$sub/kernel -name '*.ko') | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > \ + $abidir/$arch/$sub.modules + rm -rf tmp $filename + echo "done." + else + echo "FAILED." + fi + cd $origdir + done +} + +# MAIN + +# Setup abi directory +mkdir -p $abidir +echo $abi > $abidir/abiname + +# NOTE: The flavours are hardcoded, because they may have changed from the +# current build. + +getall powerpc powerpc{,-smp,64-smp} cell +getall amd64 generic server +getall i386 386 generic server virtual +getall sparc sparc64{,-smp} +getall ia64 itanium mckinley +getall lpia lpia +getall hppa hppa32 hppa64 + +rmdir $tmpdir --- linux-source-2.6.22-2.6.22.orig/debian/control +++ linux-source-2.6.22-2.6.22/debian/control @@ -0,0 +1,880 @@ +Source: linux-source-2.6.22 +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-2.6.22 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.22 with Ubuntu patches + This package provides the source code for the Linux kernel version 2.6.22. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-2.6.22/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.22 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.22 + This package provides the various readme's in the 2.6.22 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.22/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.22-15 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.22 + This package provides kernel header files for version 2.6.22, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1) +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6) +Provides: linux-kernel-headers +Conflicts: linux-kernel-headers +Replaces: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. + +Package: linux-image-2.6.22-15-386 +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on i386 + This package contains the Linux kernel image for version 2.6.22 on + i386. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Alternate x86 (486 and better) processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-386 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-386 +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on i386 + This package provides kernel header files for version 2.6.22 on + i386. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-386 +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on i386 + This package provides a kernel debug image for version 2.6.22 on + i386. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.22 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86/x86_64 + This package provides kernel header files for version 2.6.22 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86/x86_64 + This package provides a kernel debug image for version 2.6.22 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-hppa32 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.22 on + 32-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa32 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-hppa32 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.22 on + 32-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-hppa64 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-hppa64 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-itanium +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Itanium SMP + This package contains the Linux kernel image for version 2.6.22 on + Itanium SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-itanium meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-itanium +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Itanium SMP + This package provides kernel header files for version 2.6.22 on + Itanium SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-mckinley +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Itanium II SMP + This package contains the Linux kernel image for version 2.6.22 on + Itanium II SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium II SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-mckinley meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-mckinley +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Itanium II SMP + This package provides kernel header files for version 2.6.22 on + Itanium II SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit PowerPC + This package contains the Linux kernel image for version 2.6.22 on + 32-bit PowerPC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit PowerPC + This package provides kernel header files for version 2.6.22 on + 32-bit PowerPC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc64-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc64-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit PowerPC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.22 on + 32-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit PowerPC SMP + This package provides kernel header files for version 2.6.22 on + 32-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.22 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86/x86_64 + This package provides kernel header files for version 2.6.22 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86/x86_64 + This package provides a kernel debug image for version 2.6.22 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-sparc64 +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit UltraSPARC + This package contains the Linux kernel image for version 2.6.22 on + 64-bit UltraSPARC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-sparc64 +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit UltraSPARC + This package provides kernel header files for version 2.6.22 on + 64-bit UltraSPARC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-sparc64-smp +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit UltraSPARC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit UltraSPARC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-sparc64-smp +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit UltraSPARC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit UltraSPARC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-virtual +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86 + This package contains the Linux kernel image for version 2.6.22 on + x86. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtualised hardware. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-virtual +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86 + This package provides kernel header files for version 2.6.22 on + x86. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-virtual +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86 + This package provides a kernel debug image for version 2.6.22 on + x86. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-xen +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on This kernel can be used for Xen dom0 and domU + This package contains the Linux kernel image for version 2.6.22 on + This kernel can be used for Xen dom0 and domU. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Xen domO/domU + . + You likely do not want to install this package directly. Instead, install + the linux-xen meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-xen +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on This kernel can be used for Xen dom0 and domU + This package provides kernel header files for version 2.6.22 on + This kernel can be used for Xen dom0 and domU. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-rt +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on RT kernel + This package contains the Linux kernel image for version 2.6.22 on + RT kernel. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Ingo Molnar's full real time preemption patch (2.6.22.1-rt9) + . + You likely do not want to install this package directly. Instead, install + the linux-rt meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-rt +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on RT kernel + This package provides kernel header files for version 2.6.22 on + RT kernel. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-ume +Architecture: i386 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-ume meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-ume +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-cell +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on PowerPC Cell + This package contains the Linux kernel image for version 2.6.22 on + PowerPC Cell. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports PowerPC Cell processors. + . + Supports PowerPC Cell (Including PS3) + . + You likely do not want to install this package directly. Instead, install + the linux-cell meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-cell +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on PowerPC Cell + This package provides kernel header files for version 2.6.22 on + PowerPC Cell. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-lpiacompat +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded-x86 compat edition + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpiacompat meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-lpiacompat +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded-x86 compat edition + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-lpia +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded LPIA edition + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded LPIA edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded LPIA edition + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded LPIA edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.sparc +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.sparc @@ -0,0 +1,10 @@ +efi-modules +nic-pcmcia-modules +pcmcia-modules +pcmcia-storage-modules +socket-modules +irda-modules +floppy-modules +fb-modules +acpi-modules +cdrom-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.powerpc +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.powerpc @@ -0,0 +1,4 @@ +efi-modules +fb-modules +acpi-modules +cdrom-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/package-list +++ linux-source-2.6.22-2.6.22/debian/d-i/package-list @@ -0,0 +1,179 @@ +Package: acpi-modules +Depends: kernel-image +Priority: standard +Description: Support for ACPI + +Package: efi-modules +Depends: kernel-image +Priority: standard +Description: EFI support + +Package: fat-modules +Depends: kernel-image +Priority: standard +Description: FAT filesystem support + This includes Windows FAT and VFAT support. + +Package: fb-modules +Depends: kernel-image +Priority: standard +Description: Framebuffer modules + +Package: firewire-core-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Firewire (IEEE-1394) Support + +Package: floppy-modules +Depends: kernel-image +Priority: standard +Description: Floppy driver support + +Package: fs-core-modules +Depends: kernel-image +Priority: standard +Provides: ext2-modules, ext3-modules, jfs-modules, reiserfs-modules, xfs-modules +Description: Base filesystem modules + This includes ext2, ext3, jfs, reiserfs and xfs. + +Package: fs-secondary-modules +Depends: kernel-image, fat-modules +Priority: standard +Provides: ntfs-modules, ufs-modules, hfs-modules, affs-modules +Description: Extra filesystem modules + This includes support for Windows NTFS, SysV UFS, MacOS HFS and HFSPlus and + Amiga AFFS. + +Package: ide-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: IDE support + +Package: input-modules +Depends: kernel-image, usb-modules +Priority: standard +Description: Support for various input methods + +Package: ipv6-modules +Depends: kernel-image +Priority: standard +Description: Support for IPv6 networking + +Package: irda-modules +Depends: kernel-image, nic-shared-modules +Priority: standard +Description: Support for Infrared protocols + +Package: md-modules +Depends: kernel-image +Priority: standard +Description: Multi-device support (raid, device-mapper, lvm) + +Package: nic-modules +Depends: kernel-image, nic-shared-modules +Priority: standard +Description: Network interface support + +Package: nic-pcmcia-modules +Depends: kernel-image, nic-shared-modules, nic-modules +Priority: standard +Description: PCMCIA network interface support + +Package: nic-usb-modules +Depends: kernel-image, nic-shared-modules, usb-modules +Priority: standard +Description: USB network interface support + +Package: parport-modules +Depends: kernel-image +Priority: standard +Description: Parallel port support + +Package: pata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: PATA support modules + +Package: pcmcia-modules +Depends: kernel-image +Priority: standard +Description: PCMCIA Modules + +Package: pcmcia-storage-modules +Depends: kernel-image, scsi-modules +Priority: standard +Description: PCMCIA storage support + +Package: plip-modules +Depends: kernel-image, nic-shared-modules, parport-modules +Priority: standard +Description: PLIP (parallel port) networking support + +Package: ppp-modules +Depends: kernel-image, nic-shared-modules, serial-modules +Priority: standard +Description: PPP (serial port) networking support + +Package: sata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SATA storage support + +Package: scsi-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SCSI storage support + +Package: serial-modules +Depends: kernel-image +Priority: standard +Description: Serial port support + +Package: socket-modules +Depends: kernel-image +Priority: standard +Description: Unix socket support + +Package: storage-core-modules +Depends: kernel-image +Priority: standard +Provides: loop-modules +Description: Core storage support + Includes core SCSI, LibATA, USB-Storage. Also includes related block + devices for CD, Disk and Tape medium (and IDE Floppy). + +Package: usb-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Core USB support + +Package: nfs-modules +Priority: standard +Depends: kernel-image +Description: NFS filesystem drivers + Includes the NFS client driver, and supporting modules. + +Package: cdrom-modules +Priority: standard +Depends: kernel-image, storage-core-modules +Description: Legacy CDROM modules + This package contains legacy type cdrom modules. + +Package: block-modules +Priority: standard +Depends: kernel-image, storage-core-modules, parport-modules +Description: Block storage devices + This package contains the block storage devices, including DAC960 and + paraide. + +Package: message-modules +Priority: standard +Depends: kernel-image, storage-core-modules, scsi-modules +Description: Fusion and i2o storage modules + This package containes the fusion and i2o storage modules. + +Package: crypto-modules +Priority: extra +Depends: kernel-image +Description: crypto modules + This package contains crypto modules. --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.hppa +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.hppa @@ -0,0 +1,10 @@ +firewire-core-modules +efi-modules +socket-modules +irda-modules +floppy-modules +fb-modules +acpi-modules +cdrom-modules +nfs-modules +nic-usb-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/kernel-versions.in +++ linux-source-2.6.22-2.6.22/debian/d-i/kernel-versions.in @@ -0,0 +1,18 @@ +# arch version flavour installedname suffix bdep +amd64 PKGVER-ABINUM generic PKGVER-ABINUM-generic - + +hppa PKGVER-ABINUM hppa32 PKGVER-ABINUM-hppa32 y +hppa PKGVER-ABINUM hppa64 PKGVER-ABINUM-hppa64 y + +i386 PKGVER-ABINUM 386 PKGVER-ABINUM-386 - +i386 PKGVER-ABINUM generic PKGVER-ABINUM-generic - + +ia64 PKGVER-ABINUM itanium PKGVER-ABINUM-itanium - + +lpia PKGVER-ABINUM lpia PKGVER-ABINUM-lpia - + +powerpc PKGVER-ABINUM powerpc PKGVER-ABINUM-powerpc - +powerpc PKGVER-ABINUM powerpc64-smp PKGVER-ABINUM-powerpc64-smp - +powerpc PKGVER-ABINUM cell PKGVER-ABINUM-cell - + +sparc PKGVER-ABINUM sparc64 PKGVER-ABINUM-sparc64 - --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.lpia +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.lpia @@ -0,0 +1,8 @@ +efi-modules +serial-modules +cdrom-modules +plip-modules +md-modules +pcmcia-storage-modules +nic-pcmcia-modules +pcmcia-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.ia64 +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.ia64 @@ -0,0 +1,3 @@ +socket-modules +floppy-modules +cdrom-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.amd64 +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.amd64 @@ -0,0 +1,2 @@ +efi-modules +cdrom-modules --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/speakup-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/speakup-modules @@ -0,0 +1,16 @@ +speakup_keyhelp ? +speakupmain ? +speakup_acntpc ? +speakup_acntsa ? +speakup_apollo ? +speakup_audptr ? +speakup_bns ? +speakup_decext ? +speakup_decpc ? +speakup_dectlk ? +speakup_dtlk ? +speakup_keypc ? +speakup_ltlk ? +speakup_sftsyn ? +speakup_spkout ? +speakup_txprt ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/message-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/message-modules @@ -0,0 +1,13 @@ +mptbase ? +mptctl ? +mptfc ? +mptlan ? +mptsas ? +mptscsih ? +mptspi ? +i2o_block ? +i2o_bus ? +i2o_config ? +i2o_core ? +i2o_proc ? +i2o_scsi ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/nic-usb-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/nic-usb-modules @@ -0,0 +1,11 @@ +catc ? +kaweth ? +pegasus ? +prism2_usb ? +rtl8150 ? +usbnet ? +zd1211rw ? +zd1201 ? +rt2500usb ? +rt73usb ? +rt2570 ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/scsi-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/scsi-modules @@ -0,0 +1,112 @@ +# SCSI +raid_class ? +scsi_transport_spi ? +scsi_transport_fc ? +scsi_transport_iscsi ? +scsi_transport_sas ? +libiscsi ? +amiga7xx ? +a3000 ? +a2091 ? +gvp11 ? +mvme147 ? +sgiwd93 ? +cyberstorm ? +cyberstormII ? +blz2060 ? +blz1230 ? +fastlane ? +oktagon_esp_mod ? +atari_scsi ? +mac_scsi ? +mac_esp ? +sun3_scsi ? +mvme16x ? +bvme6000 ? +sim710 ? +advansys ? +psi240i ? +BusLogic ? +dpt_i2o ? +u14-34f ? +ultrastor ? +aha152x ? +aha1542 ? +aha1740 ? +aic7xxx_old ? +ips ? +fd_mcs ? +fdomain ? +in2000 ? +g_NCR5380 ? +g_NCR5380_mmio ? +NCR53c406a ? +NCR_D700 ? +NCR_Q720_mod ? +sym53c416 ? +qlogicfas408 ? +qla1280 ? +pas16 ? +seagate ? +seagate ? +t128 ? +dmx3191d ? +dtc ? +zalon7xx ? +eata_pio ? +wd7000 ? +mca_53c9x ? +ibmmca ? +eata ? +dc395x ? +tmscsim ? +megaraid ? +atp870u ? +esp ? +gdth ? +initio ? +a100u2w ? +qlogicpti ? +ide-scsi ? +mesh ? +mac53c94 ? +pluto ? +dec_esp ? +3w-xxxx ? +3w-9xxx ? +ppa ? +imm ? +jazz_esp ? +sun3x_esp ? +fcal ? +lasi700 ? +nsp32 ? +ipr ? +hptiop ? +stex ? +osst ? +sg ? +ch ? +scsi_debug ? +aacraid ? +aic7xxx ? +aic79xx ? +aic94xx ? +arcmsr ? +acornscsi_mod ? +arxescsi ? +cumana_1 ? +cumana_2 ? +ecoscsi ? +oak ? +powertec ? +eesox ? +ibmvscsic ? +libsas ? +lpfc ? +megaraid_mm ? +megaraid_mbox ? +megaraid_sas ? +qla2xxx ? +sym53c8xx ? +qla4xxx ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/crypto-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/crypto-modules @@ -0,0 +1,7 @@ +aes +blowfish +twofish +serpent +sha256 +cbc ? +ebc ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/parport-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/parport-modules @@ -0,0 +1,3 @@ +parport ? +parport_pc ? +parport_sunbpp ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/fs-secondary-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/fs-secondary-modules @@ -0,0 +1,13 @@ +# Windows filesystems; fuse is needed for ntfs-3g. +fuse ? +ntfs ? + +# UFS (Unix SysV) +ufs ? + +# Mac HFS +hfs ? +hfsplus ? + +# Amiga fs ? +affs ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/pcmcia-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/pcmcia-modules @@ -0,0 +1,8 @@ +i82092 ? +i82365 ? +pcmcia ? +pcmcia_core ? +pd6729 ? +rsrc_nonstatic ? +tcic ? +yenta_socket ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/irda-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/irda-modules @@ -0,0 +1,26 @@ +act200l-sir ? +actisys-sir ? +ali-ircc ? +donauboe ? +esi-sir ? +girbil-sir ? +ircomm ? +ircomm-tty ? +irda ? +irda-usb ? +irlan ? +irnet ? +irport ? +irtty-sir ? +litelink-sir ? +ma600-sir ? +mcp2120-sir ? +nsc-ircc ? +old_belkin-sir ? +sir-dev ? +smsc-ircc2 ? +stir4200 ? +tekram-sir ? +via-ircc ? +vlsi_ir ? +w83977af_ir ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/efi-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/efi-modules @@ -0,0 +1 @@ +efivars ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/nic-shared-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/nic-shared-modules @@ -0,0 +1,23 @@ +# PHY +8390 ? +mii ? + +# CRC modules ? +crc-ccitt ? +crc-itu-t ? + +# mac80211 stuff ? +mac80211 ? +rc80211_simple ? +cfg80211 ? + +# rt2x00 lib ? +rt2x00lib ? + +# Wireless 802.11 modules ? +ieee80211 ? +ieee80211_crypt ? +ieee80211_crypt_ccmp ? +ieee80211_crypt_tkip ? +ieee80211_crypt_wep ? +ieee80211softmac ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/sata-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/sata-modules @@ -0,0 +1,18 @@ +ahci ? +ata_piix ? +# Required by sata_sis +pata_sis ? +pdc_adma ? +sata_inic162x ? +sata_mv ? +sata_nv ? +sata_promise ? +sata_qstor ? +sata_sil ? +sata_sil24 ? +sata_sis ? +sata_svw ? +sata_sx4 ? +sata_uli ? +sata_via ? +sata_vsc ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/nic-pcmcia-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/nic-pcmcia-modules @@ -0,0 +1,19 @@ +3c574_cs ? +3c589_cs ? +airo_cs ? +atmel_cs ? +axnet_cs ? +com20020_cs ? +fmvj18x_cs ? +ibmtr_cs ? +netwave_cs ? +nmclan_cs ? +orinoco_cs ? +pcnet_cs ? +ray_cs ? +smc91c92_cs ? +wavelan_cs ? +wl3501_cs ? +xirc2ps_cs ? +xircom_cb ? +xircom_tulip_cb ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/plip-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/plip-modules @@ -0,0 +1 @@ +plip ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/acpi-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/acpi-modules @@ -0,0 +1,2 @@ +fan ? +thermal ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/ipv6-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/ipv6-modules @@ -0,0 +1 @@ +ipv6 ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/fs-core-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/fs-core-modules @@ -0,0 +1,5 @@ +ext2 ? +ext3 ? +jfs ? +reiserfs ? +xfs ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/fat-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/fat-modules @@ -0,0 +1,8 @@ +# Windows filesystems ? +fat ? +vfat ? + +# Supporting modules ? +nls_cp437 ? +nls_iso8859-1 ? +nls_utf8 ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/serial-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/serial-modules @@ -0,0 +1,3 @@ +generic_serial ? +serial_cs ? +synclink_cs ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/block-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/block-modules @@ -0,0 +1,33 @@ +cryptoloop ? +DAC960 ? +aoe ? +cciss ? +cpqarray ? +nbd ? +bpck6 ? +aten ? +bpck ? +comm ? +dstr ? +epat ? +epia ? +fit2 ? +fit3 ? +friq ? +frpw ? +kbic ? +ktti ? +on20 ? +on26 ? +paride ? +pcd ? +pd ? +pf ? +pg ? +pt ? +pktcdvd ? +ps3disk ? +sunvdc ? +sx8 ? +umem ? +xd ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/nic-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/nic-modules @@ -0,0 +1,144 @@ +3c359 ? +3c501 ? +3c503 ? +3c505 ? +3c507 ? +3c509 ? +3c515 ? +3c523 ? +3c527 ? +3c59x ? +8139cp ? +8139too ? +82596 ? +abyss ? +ac3200 ? +adm8211 ? +airo ? +airport ? +amd8111e ? +arc4 ? +arcnet ? +arc-rawmode ? +arc-rimi ? +arlan ? +at1700 ? +atmel ? +atmel_pci ? +b44 ? +bcm43xx ? +bcm43xx-mac80211 ? +bmac ? +bnx2 ? +bonding ? +cassini ? +com20020 ? +com20020-pci ? +com90io ? +com90xx ? +cs89x0 ? +de2104x ? +de4x5 ? +de600 ? +de620 ? +defxx ? +depca ? +dl2k ? +dmfe ? +dummy ? +e100 ? +e1000 ? +e2100 ? +eepro ? +eepro100 ? +eexpress ? +epic100 ? +eql ? +es3210 ? +eth16i ? +ewrk3 ? +fealnx ? +forcedeth ? +ps3_gelic ? +hamachi ? +hermes ? +hp ? +hp100 ? +hp-plus ? +ibmtr ? +ipddp ? +ipw2100 ? +ipw2200 ? +ipw3945 ? +ixgb ? +lance ? +lanstreamer ? +lasi_82596 ? +lne390 ? +lp486e ? +mace ? +mv643xx_eth ? +myri_sbus ? +natsemi ? +ne ? +ne2 ? +ne2k-pci ? +ne3210 ? +netconsole ? +ni5010 ? +ni52 ? +ni65 ? +niu ? +ns83820 ? +olympic ? +orinoco ? +orinoco_pci ? +orinoco_plx ? +orinoco_tmd ? +pcnet32 ? +prism54 ? +r8169 ? +rate_control ? +rfc1051 ? +rfc1201 ? +rrunner ? +rt2400 ? +rt2500 ? +rt61pci ? +s2io ? +shaper ? +sis190 ? +sis900 ? +spidernet ? +skfp ? +skge ? +sk98lin ? +sky2 ? +smc9194 ? +smc-ultra ? +smc-ultra32 ? +starfire ? +strip ? +sunbmac ? +sundance ? +sungem ? +sungem_phy ? +sunhme ? +sunlance ? +sunqe ? +sunvnet ? +tg3 ? +tlan ? +tms380tr ? +tmspci ? +tulip ? +tun ? +typhoon ? +uli526x ? +via-rhine ? +via-velocity ? +wavelan ? +wd ? +winbond-840 ? +yellowfin ? +znet ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/md-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/md-modules @@ -0,0 +1,17 @@ +dm-crypt ? +dm-emc ? +dm-mirror ? +dm-mod ? +dm-multipath ? +dm-round-robin ? +dm-snapshot ? +dm-zero ? +faulty ? +linear ? +md-mod ? +multipath ? +raid0 ? +raid10 ? +raid1 ? +raid456 ? +xor ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/pcmcia-storage-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/pcmcia-storage-modules @@ -0,0 +1,6 @@ +pata_pcmcia ? +qlogic_cs ? +fdomain_cs ? +aha152x_cs ? +nsp_cs ? +sym53c500_cs ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/pata-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/pata-modules @@ -0,0 +1,44 @@ +ata_generic ? +pata_ali ? +pata_amd ? +pata_artop ? +pata_atiixp ? +pata_cmd640 ? +pata_cmd64x ? +pata_cs5520 ? +pata_cs5530 ? +pata_cs5535 ? +pata_cypress ? +pata_efar ? +pata_hpt366 ? +pata_hpt37x ? +pata_hpt3x2n ? +pata_hpt3x3 ? +pata_isapnp ? +pata_it8213 ? +pata_it821x ? +pata_ixp4xx_cf ? +pata_jmicron ? +pata_legacy ? +pata_marvell ? +pata_mpc52xx ? +pata_mpiix ? +pata_netcell ? +pata_ns87410 ? +pata_oldpiix ? +pata_opti ? +pata_optidma ? +pata_pdc2027x ? +pata_pdc202xx_old ? +pata_platform ? +pata_qdi ? +pata_radisys ? +pata_rz1000 ? +pata_sc1200 ? +pata_scc ? +pata_serverworks ? +pata_sil680 ? +pata_sl82c105 ? +pata_triflex ? +pata_via ? +pata_winbond ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/ppp-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/ppp-modules @@ -0,0 +1,6 @@ +ppp_async ? +ppp_deflate ? +ppp_mppe ? +pppoe ? +pppox ? +ppp_synctty ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/fb-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/fb-modules @@ -0,0 +1,3 @@ +fbcon ? +vesafb ? +vga16fb ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/floppy-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/floppy-modules @@ -0,0 +1 @@ +floppy ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/cdrom-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/cdrom-modules @@ -0,0 +1,10 @@ +ztcd ? +cdu31a ? +gscd ? +mcdx ? +sbpcd ? +sonycd535 ? +cm206 ? +isp16 ? +optcd ? +sjcd ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/nfs-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/nfs-modules @@ -0,0 +1,3 @@ +nfs ? +lockd ? +sunrpc ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/storage-core-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/storage-core-modules @@ -0,0 +1,42 @@ +# For SATA and PATA +libata ? + +# For SCSI (and for ATA and USB) +scsi_mod ? + +# IDE Core support +ide-core + +# USB Core for usb-storage ? +usbcore ? + +## Block level modules for each bus type ? + +# Generic cdrom support ? +cdrom ? + +# PS3 storage lib +ps3stor_lib ? +# PS3 Optical Storage +ps3rom ? + +# Anything that wants cdrom support will want isofs too +isofs ? + +# IDE Block devices ? +ide-cd ? +ide-disk ? +ide-floppy ? +ide-tape ? + +# SCSI Block devices ? +sd_mod ? +sr_mod ? +st ? + +# USB Storage modull ? +usb-storage ? + +# Loop modules (loop is built-in on sparc64) +loop ? +cloop ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/input-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/input-modules @@ -0,0 +1,12 @@ +atkbd ? +evdev ? +hil_kbd ? +hilkbd ? +hil_mlc ? +hp_sdc ? +hp_sdc_mlc ? +i8042 ? +mousedev ? +psmouse ? +usbhid ? +usbkbd ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/ide-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/ide-modules @@ -0,0 +1,45 @@ +ide-generic ? +ide-pnp ? +icside ? +rapide ? +bast-ide ? +ide-cris ? +ali14xx ? +dtc2278 ? +ht6560b ? +qd65xx ? +umc8672 ? +ide-cs ? +hd ? +swarm ? +au1xxx-ide ? +aec62xx ? +alim15x3 ? +amd74xx ? +atiixp ? +cmd64x ? +cs5520 ? +cs5530 ? +cs5535 ? +sc1200 ? +cy82c693 ? +hpt34x ? +hpt366 ? +it821x ? +jmicron ? +ns87415 ? +opti621 ? +pdc202xx_old ? +pdc202xx_new ? +piix ? +rz1000 ? +serverworks ? +sgiioc4 ? +siimage ? +sis5513 ? +sl82c105 ? +slc90e66 ? +triflex ? +trm290 ? +via82cxxx ? +generic ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/usb-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/usb-modules @@ -0,0 +1,5 @@ +ehci-hcd ? +ohci-hcd ? +sl811-hcd ? +uhci-hcd ? +usbserial ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/firewire-core-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/firewire-core-modules @@ -0,0 +1,4 @@ +ieee1394 ? +ohci1394 ? +sbp2 ? +eth1394 ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/modules/socket-modules +++ linux-source-2.6.22-2.6.22/debian/d-i/modules/socket-modules @@ -0,0 +1 @@ +af_packet ? --- linux-source-2.6.22-2.6.22.orig/debian/d-i/kernel-versions +++ linux-source-2.6.22-2.6.22/debian/d-i/kernel-versions @@ -0,0 +1,18 @@ +# arch version flavour installedname suffix bdep +amd64 2.6.22-15 generic 2.6.22-15-generic - + +hppa 2.6.22-15 hppa32 2.6.22-15-hppa32 y +hppa 2.6.22-15 hppa64 2.6.22-15-hppa64 y + +i386 2.6.22-15 386 2.6.22-15-386 - +i386 2.6.22-15 generic 2.6.22-15-generic - + +ia64 2.6.22-15 itanium 2.6.22-15-itanium - + +lpia 2.6.22-15 lpia 2.6.22-15-lpia - + +powerpc 2.6.22-15 powerpc 2.6.22-15-powerpc - +powerpc 2.6.22-15 powerpc64-smp 2.6.22-15-powerpc64-smp - +powerpc 2.6.22-15 cell 2.6.22-15-cell - + +sparc 2.6.22-15 sparc64 2.6.22-15-sparc64 - --- linux-source-2.6.22-2.6.22.orig/debian/d-i/exclude-modules.i386 +++ linux-source-2.6.22-2.6.22/debian/d-i/exclude-modules.i386 @@ -0,0 +1 @@ +efi-modules --- linux-source-2.6.22-2.6.22.orig/debian/copyright +++ linux-source-2.6.22-2.6.22/debian/copyright @@ -0,0 +1,30 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-source-2.6.22-2.6.22.orig/debian/control-scripts/preinst +++ linux-source-2.6.22-2.6.22/debian/control-scripts/preinst @@ -0,0 +1,299 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.preinst --- +# Author : Manoj Srivastava ( srivasta@tiamat.datasync.com ) +# Created On : Sun Jun 14 03:38:02 1998 +# Created On Node : tiamat.datasync.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Sun Sep 24 14:04:42 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 99 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# + +# +#use strict; #for debugging + +use Debconf::Client::ConfModule qw(:all); +version('2.0'); +my $capb=capb("backup"); + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom + # or elilo +my $image_dir = "/boot"; # where the image is located +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_src_link = 'YES'; # There is no harm in checking the link +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = ''; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; + +die "Pre inst Internal error. Aborting." unless $version; + +exit 0 if $ARGV[0] =~ /abort-upgrade/; +exit 1 unless $ARGV[0] =~ /(install|upgrade)/; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_src_link = '' if /^\s*relink_src_link\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_src_link = 'Yes' if /^\s*relink_src_link\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + $have_conffile = "Yes"; # stop perl complaining + } +} + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +# About to upgrade this package from version $2 TO THIS VERSION. +# "prerm upgrade" has already been called for the old version of +# this package. + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +sub check { + my $version = shift; + my $lib_modules="$modules_base/$version"; + my $message = ''; + + if (-d "$lib_modules") { + opendir(DIR, $lib_modules) || die "can’t opendir $lib_modules: $!"; + my @children = readdir(DIR); + if ($#children > 1) { + my @dirs = grep { -d "$lib_modules/$_" } @children; + if ($#dirs > 1) { # we have subdirs + my $dir_message=''; + for my $dir (@dirs) { + if ($dir =~/kernel$/) { + $dir_message="An older install was detected.\n"; + } + else { + $dir_message="Module sub-directories were detected.\n" + unless $dir_message; + } + } + $message += $dir_message if $dir_message; + } + + my @links = grep { -l "$lib_modules/$_" } @children; + if ($#links > -1) { + my $links_message = ''; + for my $link (@links) { + next if ($link =~ /^build$/); + next if ($link =~ /^source$/); + $links_message = "Symbolic links were detected in $modules_base/$version.\n"; + } + $message += $links_message if $links_message; + } + my @files = grep { -f "$lib_modules/$_" } @children; + $message += "Additional files also exist in $modules_base/$version.\n" + if ($#files > -1); + } + } + else { $message .= "$lib_modules does not exist. ";} + return $message; +} + +if (-d "$modules_base/$version") { + my $errors=check($version); + warn "Info:\n$errors\n" if $errors; +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$preinst_hook") { + &run_hook("preinst", $preinst_hook); +} +if (-d "/etc/kernel/preinst.d") { + print STDERR "Examining /etc/kernel/preinst.d/\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d") && + die "Failed to process /etc/kernel/preinst.d"; +} +if (-d "/etc/kernel/preinst.d/$version") { + print STDERR "Examining /etc/kernel/preinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d/$version") && + die "Failed to process /etc/kernel/preinst.d/$version"; +} +print STDERR "Done.\n"; + +exit 0; + +__END__ + + --- linux-source-2.6.22-2.6.22.orig/debian/control-scripts/postinst +++ linux-source-2.6.22-2.6.22/debian/control-scripts/postinst @@ -0,0 +1,1087 @@ +#! /usr/bin/perl +# OriginalAuthor : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# +# Customized for Ubuntu by: Ben Collins + +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom, arcboot or delo +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $relative_links = ""; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally we do not +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $notifier = "/usr/share/update-notifier/notify-reboot-required"; +my $package_name = "linux-image-$version"; +my $explicit_do_loader = 'Yes'; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; +$Loader = "ARCBOOT" if $loader =~ /^arcboot/io; +$Loader = "DELO" if $loader =~ /^delo/io; + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; + +# Ignore all invocations except when called on to configure. +exit 0 unless $ARGV[0] =~ /configure/; + +my $DEBUG = 0; + +# Do some preliminary sanity checks here to ensure we actually have an +# valid image dir +chdir('/') or die "could not chdir to /:$!\n"; +die "Internal Error: ($image_dir) is not a directory!\n" + unless -d $image_dir; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; +die "Internal Error: ($realimageloc) is not a directory!\n" + unless -d $realimageloc; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlink\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $explicit_do_loader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $explicit_do_loader = "YES" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + + +# For some versions of kernel-package, we had this warning in the +# postinst, but the rules did not really interpolate the value in. +# Here is a sanity check. +my $pattern = "=" . "I"; +$initrd=~ s/^$pattern$//; + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; # same as realimageloc +} + +# Tack on at least one trainling / +$image_dest = "$image_dest/"; +$image_dest =~ s|^/*|/|o; +$image_dest =~ s|/+$|/|o; + +if (! -d "$image_dest") { + die "Expected Image Destination dir ($image_dest) to be a valid directory!\n"; +} + +# sanity +if (!($do_bootfloppy || $do_bootloader)) { + $do_boot_enable = ''; +} +if ($do_symlink && $no_symlink) { + warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n"; + $no_symlink = 0; +} + +# most of our work is done in $image_dest (nominally /) +chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz"; } # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz"; } # Default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +die "Internal Error: Could not find image (" . $realimageloc + . "$kimage-$version)\n" unless -e $realimageloc + . "$kimage-$version"; + +# search for the boot loader in the path +my $loader_exec; +($loader_exec = $loader) =~ s|.*/||; +my ($loaderloc) = grep -x, map "$_/$loader_exec", + map { length($_) ? $_ : "." } split /:/, $ENV{PATH}; + + +###################################################################### +###################################################################### +########### Test whether a relative symlinkwould be OK ####### +###################################################################### +###################################################################### +sub test_relative { + my %params = @_; + my $cwd; + + die "Internal Error: Missing Required paramater 'Old Dir' " + unless $params{'Old Dir'}; + die "Internal Error: Missing Required paramater New Dir' " + unless $params{'New Dir'}; + + + die "Internal Error: No such dir $params{'Old Dir'} " + unless -d $params{'Old Dir'}; + die "Internal Error: No such dir $params{'New Dir'} " + unless -d $params{'New Dir'}; + + warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}" + if $DEBUG; + chomp($cwd = `pwd`); + chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!"; + my $ok = 0; + $params{'Old Dir'} =~ s|^/*||o; + if (-d $params{'Old Dir'} ) { + if (defined $params{'Test File'}) { + if (-e $params{'Old Dir'} . $params{'Test File'}) { + $ok = 1; + } + } else { + $ok = 1; # well, backward compatibility + } + } + chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!"; + return $ok; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# sub CanonicalizePath { +# my $path = join '/', @_; +# my @work = split '/', $path; +# my @out; +# my $is_absolute; + +# if (@work && $work[0] eq "") { +# $is_absolute = 1; shift @work; +# } + +# while (@work) { +# my $seg = shift @work; +# if ($seg eq "." || $seg eq "") { +# } +# elsif ($seg eq "..") { +# if (@out && $out[-1] ne "..") { +# pop @out; +# } +# else { +# # Leading "..", or "../..", etc. +# push @out, $seg; +# } +# } +# else { +# push @out, $seg; +# } +# } + +# unshift @out, "" if $is_absolute; +# return join('/', @out); +# } +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + +sub spath { + my %params = @_; + + die "Missing Required paramater 'Old'" unless $params{'Old'}; + die "Missing Required paramater 'New'" unless $params{'New'}; + + my @olddir = split '/', `readlink -q -m $params{'Old'}`; + my @newdir = split '/', `readlink -q -m $params{'New'}`; + my @outdir = @olddir; + + my $out = ''; + my $i; + for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) { + $out++ if ($olddir[$i] ne $newdir[$i]); + shift @outdir unless $out; + unshift @outdir, ".." if $out; + } + if ($#newdir > $#olddir) { + for ($i=0; $i < $#newdir; $i++) { + unshift @outdir, ".."; + } + } + return join ('/', @outdir); +} +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + + +# This routine actually moves the kernel image +# From: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +# To: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# Note that the image is moved to a versioned destination, but ordinary +# symlinks we create otherwise are not normally versioned +sub really_move_image { + my $src_dir = $_[0]; + my $target = $_[1]; + my $dest_dir = $_[2]; + + warn "Really move image: src_dir=$src_dir, target=$target,\n destdir=$dest_dir" + if $DEBUG; + if (-e "$target") { + # we should be in dir $dest_dir == $image_dest /, normally + rename("$target", "$target.$$") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target $target.$$" if $DEBUG; + } + warn "mv -f $src_dir$target $target" if $DEBUG; + my $ret = system("mv -f " . $src_dir . "$target " . + " $target"); + if ($ret) { + die("Failed to move " . $src_dir . "$target to " + . $dest_dir . "$target.\n"); + } + # Ok, now we may clobber the previous .old files + if (-e "$target.$$") { + rename("$target.$$", "$target.old") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target.$$ $target " if $DEBUG; + } +} + +# Normally called after really_move_image; and only called if we asked for +# reversed link this routine reverses the symbolic link that is notmally +# created. Since the real kernel image has been moved over to +# $image_dest/$kimage-$version. So, this routine links +# From: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# To: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +sub really_reverse_link { + my $src_dir = $_[0]; + my $link_name = $_[1]; + my $dest_dir = $_[2]; + warn "Really reverse link: src_dir=$src_dir, link name=$link_name\n" . + "\tdestdir=$dest_dir" if $DEBUG; + + my $Old = $dest_dir; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $src_dir, + 'Test File' => "$link_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$src_dir" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + link($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to symbolic-link " . $dest_dir . "$link_name to " . $src_dir + . "$link_name .\n"); + warn "ln " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } + else { + symlink($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to link " . $dest_dir . "$link_name to " . $src_dir . + "$link_name .\n"); + warn "ln -s " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } +} + +# This routine is invoked if there is a symbolic link in place +# in $image_dest/$kimage -- so a symlink exists in the destination. +# What we are trying to determine is if we need to move the symbolic link over +# to the the .old location +sub move_p { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + my $force_move = 0; + warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" . + "\timage_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink || $reverse_symlink) { + # we do not want links, yet we have a symbolic link here! + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though no_symlink is defined\n" if $no_symlink; + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though reverse_symlink is defined\n" if $reverse_symlink; + # make sure we change this state of affairs + $force_move = 1; + return $force_move; + } + + warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n" + if $DEBUG; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + my $target = `readlink -q -m "${realimageloc}${kimage-$version}"`; + $real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target); + + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a dangling link" . + "to $real_target\n"; + $force_move = 1; + return $force_move; + } + + + warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG; + warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG; + my $cwd; + chomp ($cwd=`pwd`); + if ($vmlinuz_target !~ m|^/|o) { + $vmlinuz_target = $cwd . "/" . $vmlinuz_target; + $vmlinuz_target =~ s|/+|/|o; + } + $vmlinuz_target = `readlink -q -m $vmlinuz_target`; + + if ("$vmlinuz_target" ne "$target") { + warn "DEBUG: We need to handle this.\n" if $DEBUG; + if ($minimal_swap) { + warn "DEBUG: Minimal swap.\n" if $DEBUG; + if (-l "$kimage.old") { + warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG; + my $old_target = readlink "$kimage.old"; + my $real_old_target = ''; + $real_old_target=abs_path($old_target) if defined ($old_target); + + if ($real_old_target && -f "$real_old_target") { + if ($old_target !~ m|^/|o) { + $old_target = $cwd . "/" . $old_target; + $old_target =~ s|/+|/|o; + } + $old_target = `readlink -q -m $old_target`; + if ("$old_target" ne "$target") { + $force_move = 1; + warn "DEBUG: Old link ($old_target) does not point to us ($target)\n" + if $DEBUG; + } + else { # The .old points to the current + warn "$kimage.old --> $target -- doing nothing"; + $force_move = 0; + } + } + else { + warn "DEBUG: Well, the old link does not exist -- so we move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: No .old link -- OK to move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: ok, minimal swap is no-- so we move.\n" + if $DEBUG; + $force_move = 1; + } + } + else { # already have proper link + warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing"; + $force_move = 0; + } + return $force_move; +} + + +# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old) +# It pays attention to whether we should the fact whether we should be using +# hard links or not. +sub really_move_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # don't clobber $kimage.old quite yet + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + my $Old = $src_dir; + my $cwd; + + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln ${Old}${image_name} $kimage" if $DEBUG; + if (! link("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + else { + warn "ln -s ${Old}${image_name} $kimage" if $DEBUG; + if (! symlink("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to symbolic-link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + + # Ok, now we may clobber the previous .old file + if (-l "$kimage.old" || ! -e "$kimage.old" ) { + rename("$kimage.$$", "$kimage.old"); + warn "mv $kimage.$$ $kimage.old" if $DEBUG; + } + else { + warn "$kimage.old is not a symlink, not clobbering\n"; + warn "rm $kimage.$$"; + unlink "$kimage.$$" if $DEBUG; + } +} + +# This routine handles a request to do symlinks, but there is no +# symlink file already there. Either we are supposed to use copy, or we are +# installing on a pristine system, or the user does not want symbolic links at +# all. We use a configuration file to tell the last two cases apart, creating +# a config file if needed. +sub handle_missing_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink) { + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc . + "$image_name " . " $kimage"); + if ($ret) { + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + elsif ($reverse_symlink) { + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . "$kimage"); + if ($ret) { + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + else { + if (! $have_conffile) { + my $ret; + my $answer=''; + $do_symlink = "Yes"; + + if (open(CONF, ">$CONF_LOC")) { + print CONF "# Kernel Image management overrides\n"; + print CONF "# See kernel-img.conf(5) for details\n"; + if ($loader =~ /palo/i) { + print CONF "link_in_boot = Yes\n"; + print CONF "do_symlinks = Yes\n"; + print CONF "relative_links = Yes\n"; + print CONF "do_bootloader = No\n"; + } else { + print CONF "do_symlinks = $do_symlink\n"; + } + close CONF; + } + $have_conffile = "Yes"; + } + } + + if (! $no_symlink && $do_symlink =~ /Yes/i) { + my $Old = $realimageloc; + my $New = $image_dest; + my $Name = "$image_name"; + my $Link_Dest = "$kimage"; + + if ($reverse_symlink) { + $Old = $image_dest; + $New = $realimageloc; + $Name = "$kimage"; + $Link_Dest = $realimageloc . "$image_name"; + } + if (test_relative ('Old Dir' => $Old, + 'New Dir' => $New, + 'Test File' => $Name)) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$New" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + symlink($Old . "$Name", "$Link_Dest") || + die("Failed to symbolic-link ${Old}$Name to $Link_Dest.\n"); + warn "ln -s ${Old}$Name $Link_Dest" if $DEBUG; + + } +} + +# This routine handles the rest of the cases, where the user has requested +# non-traditional handling, like using cp, or reverse symlinks, or hard links. +sub handle_non_symlinks { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Save the current image. We do this in all four cases + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + + ##,#### + # case One + #`#### + if ($no_symlink) { + # Maybe /$image_dest is on a dos system? + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Two + #`#### + elsif ($reverse_symlink) { # Maybe /$image_dest is on a dos system? + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . $image_dest . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + my $Old = $image_dest; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $realimageloc, + 'Test File' => "$kimage")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$realimageloc" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! link($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not link " . $image_dest . + "$kimage to $image_name :$!"; + } + } + else { + warn "ln -s " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! symlink($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not symlink " . $image_dest . + "$kimage to $image_name :$!"; + } + } + } + ##,#### + # case Three + #`#### + elsif ($use_hard_links =~ m/YES/i ) { + # Ok then. this ought to be a hard link, and hence fair game + # don't clobber $kimage.old quite yet + my $Old = $realimageloc; + my $cwd; + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + warn "ln " . $Old . "$image_name " . "$kimage" if $DEBUG; + if (! link($Old . "$image_name", "$kimage")) { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + die("Failed to link " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Four + #`#### + else { + # We just use cp + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + # Ok, now we may clobber the previous .old file + warn "mv $kimage.$$ $kimage.old if -e $kimage.$$" if $DEBUG; + rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$"; +} + +# This routine is responsible for setting up the symbolic links +# So, the actual kernel image lives in +# $realimageloc/$image_name (/boot/vmlinuz-2.6.12). +# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz) +sub image_magic { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = "$kimage-$version"; + my $src_dir = $realimageloc; + warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Well, in any case, if the destination (the symlink we are trying + # to create) is a directory, we should do nothing, except throw a + # diagnostic. + if (-d "$kimage" ) { + die ("Hmm. $kimage is a directory, which I did not expect. I am\n" . + "trying to create a symbolic link with that name linked to \n" . + "$image_dest . Since a directory exists here, my assumptions \n" . + "are way off, and I am aborting.\n" ); + exit (3); + } + + if ($move_image) { # Maybe $image_dest is in on dos, or something? + # source dir, link name, dest dir + really_move_image( $realimageloc, $image_name, $image_dest); + really_reverse_link($realimageloc, $image_name, $image_dest) + if $reverse_symlink; + return; + } + + if (-l "$kimage") { # There is a symbolic link + warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG; + my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir); + + if ($force_move) { + really_move_link($kimage, $image_dest, $image_name, $src_dir); + } + } + elsif (! -e "$kimage") { + # Hmm. Pristine system? How can that be? Installing from scratch? + # Or maybe the user does not want a symbolic link here. + # Possibly they do not want a link here. (we should be in / + # here[$image_dest, really] + handle_missing_link($kimage, $image_dest, $image_name, $src_dir); + } + elsif (-e "$kimage" ) { + # OK, $kimage exists -- but is not a link + handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir); + } +} + +###################################################################### +###################################################################### +###################################################################### +###################################################################### + +# We may not have any modules installed +if ( -d "$modules_base/$version" ) { + print STDERR "Running depmod.\n"; + my $ret = system("depmod -a -F $realimageloc/System.map-$version $version"); + if ($ret) { + print STDERR "Failed to run depmod\n"; + exit(1); + } +} + + + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + print STDERR "Finding valid ramdisk creators.\n"; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +# The initrd symlink should probably be in the same dir that the +# symlinks are in +if ($initrd) { + my $success = 0; + + # Update-initramfs is called slightly different than mkinitrd and + # mkinitramfs. XXX It should really be made compatible with this stuff + # some how. + my $upgrading = 1; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + $upgrading = 0; + } + my $ret = system("$ramdisk " . ($upgrading ? "-u" : "-c") . " -k " . $version . " >&2"); + $success = 1 unless $ret; + die "Failed to create initrd image.\n" unless $success; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic("initrd.img", $image_dest); + } + else { + if (! -e "initrd.img") { + handle_missing_link("initrd.img", $image_dest, "initrd.img-$version", + $realimageloc); + } + else { + print STDERR + "Not updating initrd symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } + } + + if ($initrd && -l "initrd" ) { + unlink "initrd"; + } + + if ($initrd && -l "$image_dir/initrd" && ! $link_in_boot) { + unlink "$image_dir/initrd"; + } +} +else { # Not making an initrd emage + if (-l "initrd.img") { + # Ooh, last image was an initrd image? in any case, we should move it. + my $target = readlink "initrd.img"; + my $real_target = ''; + $real_target = abs_path($target) if defined ($target); + + if (!defined($target) || ! -f "$real_target") { + # Eh. dangling link. can safely be removed. + unlink("initrd.img"); + } else { + if (-l "initrd.img.old" || ! -e "initrd.img.old" ) { + rename("initrd.img", "initrd.img.old"); + } else { + warn "initrd.img.old is not a symlink, not clobbering\n"; + unlink("initrd.img"); + } + } + } +} + +# Warn of a reboot +if (-x $notifier) { + system($notifier); +} + +# Let programs know not to hibernate if the kernel that would be used for +# resume-from-hibernate is likely to differ from the currently running kernel. +system("mountpoint -q /var/run"); +if ($? eq 0) { + system("touch /var/run/do-not-hibernate"); +} + +# Only change the symlinks if we are not being upgraded +if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic($kimage, $image_dest); +} +else { + if (! -e "$kimage") { + handle_missing_link($kimage, $image_dest, "$kimage-$version", + $realimageloc); + } + else { + print STDERR + "Not updating image symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } +} + +# We used to have System.* files in / +if (-e "/System.map" || -e "/System.old") { + unlink '/System.map' if -e '/System.map'; + unlink '/System.old' if -e '/System.old'; +} + +# creating some info about kernel and initrd +if ($DEBUG) { + my $ksize=sprintf("%.0f",(stat($realimageloc . + "$kimage-$version"))[7]/1024)."kB"; + my $initrdsize=''; + if ($initrd) { + $initrdsize=sprintf("%.0f",(stat($realimageloc . + "initrd.img-$version"))[7]/1024)."kB"; + } + + print STDERR <<"EOMSG"; +A new kernel image has been installed at $realimageloc$kimage-$version + (Size: $ksize) + +Symbolic links, unless otherwise specified, can be found in $image_dest + +EOMSG + ; + + if ($initrd) { + print STDERR <<"EOMSGA"; + + Initial rootdisk image: ${realimageloc}initrd.img-$version (Size: $initrdsize) +EOMSGA + ; + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postinst_hook) { + &run_hook("postinst", $postinst_hook); +} + +if (-d "/etc/kernel/postinst.d") { + print STDERR "Examining /etc/kernel/postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d") && + die "Failed to process /etc/kernel/postinst.d"; +} + +if (-d "/etc/kernel/postinst.d/$version") { + print STDERR "Examining /etc/kernel/postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d/$version") && + die "Failed to process /etc/kernel/postinst.d/$version"; +} + +LOADER: { + last unless $do_boot_enable; # Exit if explicitly asked to + + last if $loader =~ /silo/i; # SILO does not have to be executed. + last if $loader =~ /yaboot/i; # yaboot does not have to be executed. + last if $loader =~ /milo/i; # MILO does not have to be executed. + last if $loader =~ /nettrom/i; # NETTROM does not have to be executed. + last if $loader =~ /arcboot/i; # ARCBOOT does not have to be executed. + last if $loader =~ /delo/i; # DELO does not have to be executed. + last if $loader =~ /quik/i; # maintainer asked quik invocation to be ignored + + last unless $loaderloc; + last unless -x $loaderloc; + last unless $do_bootloader; + + if (-T "/etc/$loader.conf") { + # Trust and use the existing lilo.conf. + print STDERR "You already have a $Loader configuration in /etc/$loader.conf\n"; + my $ret = &run_lilo(); + exit $ret if $ret; + } +} + + +sub run_lilo (){ + my $ret; + # Try and figure out if the user really wants lilo to be run -- + # since the default is to run the boot laoder, which is ! grub -- but + # the user may be using grub now, and not changed the default. + + # So, if the user has explicitly asked for the loader to be run, or + # if there is no postinst hook, or if there is no grub installed -- + # we are OK. Or else, we ask. + if ($explicit_do_loader || (! ($postinst_hook && -x '/usr/sbin/grub'))) { + print STDERR "Running boot loader as requested\n"; + } else { + print STDERR "Ok, not running $loader\n"; + } + if ($loader =~ /^lilo/io or $loader =~ /vmelilo/io) { + print STDERR "Testing $loader.conf ... \n"; + unlink $temp_file_name; # security + $ret = system("$loaderloc -t >$temp_file_name 2>&1"); + if ($ret) { + print STDERR "Boot loader test failed\n"; + return $ret; + } + unlink "$temp_file_name"; + print STDERR "Testing successful.\n"; + print STDERR "Installing the "; + print STDERR "partition " if $loader =~ /^lilo/io; + print STDERR "boot sector... \n"; + } + + print STDERR "Running $loaderloc ... \n"; + if ($loader =~ /^elilo/io) { + $ret = system("$loaderloc 2>&1 | tee $temp_file_name"); + } else { + $ret = system("$loaderloc >$temp_file_name 2>&1"); + } + if ($ret) { + print STDERR "Boot loader failed to run\n"; + return $ret; + } + unlink $temp_file_name; + print STDERR "Installation successful.\n"; + return 0; +} + +exit 0; + +__END__ + --- linux-source-2.6.22-2.6.22.orig/debian/control-scripts/postrm +++ linux-source-2.6.22-2.6.22/debian/control-scripts/postrm @@ -0,0 +1,376 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.postrm --- +# Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com ) +# Created On : Sat May 15 11:05:13 1999 +# Created On Node : glaurung.green-gryphon.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Wed Sep 13 11:26:19 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 57 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# $Id: image.postrm,v 1.31 2003/10/07 16:24:20 srivasta Exp $ +# + + +# +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally, we don't +my $warn_initrd = 'YES'; # Normally we do +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # we shall not create a dangling link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +chdir('/') or die "could not chdir to /:$!\n"; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $warn_initrd = '' if /^\s*warn_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $warn_initrd = "Yes" if /^\s*warn_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; + $image_dest =~ s|^/*|/|o; +} + +$image_dest = "$image_dest/"; +$image_dest =~ s|/+$|/|o; + +# The destdir may be gone by now. +if (-d "$image_dest") { + chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; +} + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) {$kimage = "vmlinuz"} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) {$kimage = "vmlinuz"} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;} +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage;} +else {$kimage = "vmlinuz"} # default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub remove_sym_link { + my $bad_image = $_[0]; + + warn "Removing symbolic link $bad_image \n"; + if ($loader =~ /lilo/i) + { + warn "Unless you used the optional flag in lilo, \n"; + } + warn " you may need to re-run your boot loader" . ($loader ? "[$loader]":"") + . "\n"; + # Remove the dangling link + unlink "$bad_image"; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub CanonicalizePath { + my $path = join '/', @_; + my @work = split '/', $path; + my @out; + my $is_absolute; + + if (@work && $work[0] eq "") { $is_absolute = 1; shift @work; } + + while (@work) { + my $seg = shift @work; + if ($seg eq "." || $seg eq "") { + } elsif ($seg eq "..") { + if (@out && $out[-1] ne "..") { + pop @out; + } else { + # Leading "..", or "../..", etc. + push @out, $seg; + } + } else { + push @out, $seg; + } + } + + unshift @out, "" if $is_absolute; + return join('/', @out); +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# This removes dangling symlinks. What do we do about hard links? Surely a +# something with the nane $image_dest . "$kimage" ought not to be left behind? +sub image_magic { + my $kimage = $_[0]; + my $image_dest = $_[1]; + + if (-l "$kimage") { + # There is a symbolic link + my $force_move = 0; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + $real_target = abs_path($vmlinuz_target) if defined ($vmlinuz_target); + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a damaged link\n"; + # Remove the dangling link + &remove_sym_link("$kimage"); + } + else { + my $canonical_target = CanonicalizePath("$vmlinuz_target"); + if (! -e $canonical_target) { + warn "The link " . $image_dest . "$kimage is a dangling link\n"; + &remove_sym_link("$kimage"); + } + } + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + warn "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + warn "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postrm_hook) { + &run_hook("postrm", $postrm_hook); +} +if (-d "/etc/kernel/postrm.d") { + warn "Examining /etc/kernel/postrm.d .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d") && + die "Failed to process /etc/kernel/postrm.d"; +} +if (-d "/etc/kernel/postrm.d/$version") { + warn "Examining /etc/kernel/postrm.d/$version .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d/$version") && + die "Failed to process /etc/kernel/postrm.d/$version"; +} + +# check and remove damaged and dangling symlinks +if ($ARGV[0] !~ /upgrade/) { + system("$ramdisk -d -k " . $version . " > /dev/null 2>&1"); + if (-f $realimageloc . "initrd.img-$version.bak") { + unlink $realimageloc . "initrd.img-$version.bak"; + } + image_magic($kimage, $image_dest); + image_magic($kimage . ".old", $image_dest); + image_magic("initrd.img", $image_dest) if $initrd; + image_magic("initrd.img.old", $image_dest) if $initrd; +} + + +# Ignore all invocations except when called on to purge. +exit 0 unless $ARGV[0] =~ /purge/; + +my @files_to_remove = qw{ + modules.dep modules.isapnpmap modules.pcimap + modules.usbmap modules.parportmap + modules.generic_string modules.ieee1394map + modules.ieee1394map modules.pnpbiosmap + modules.alias modules.ccwmap modules.inputmap + modules.symbols build source modules.ofmap + }; + +foreach my $extra_file (@files_to_remove) { + if (-f "/lib/modules/$version/$extra_file") { + unlink "/lib/modules/$version/$extra_file"; + } +} + +if (-d "/lib/modules/$version" ) { + system ("rmdir", "/lib/modules/$version"); +} + +exit 0; + +__END__ + + + + + + --- linux-source-2.6.22-2.6.22.orig/debian/control-scripts/prerm +++ linux-source-2.6.22-2.6.22/debian/control-scripts/prerm @@ -0,0 +1,294 @@ +#! /usr/bin/perl +# -*- Mode: Perl -*- +# image.prerm --- +# Author : root ( root@melkor.pilgrim.umass.edu ) +# Created On : Fri May 17 03:28:59 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:14:17 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 85 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# $Id: image.prerm,v 1.22 2003/10/07 16:24:20 srivasta Exp $ +# +# +#use strict; + +$|=1; +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlinks = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +my $DEBUG = 0; + +# Variables used +my $image=''; +my $ret=0; +my $seen=''; +my $answer=''; +my $running = ''; +my $WouldInvalidate = 0; + +if ($ARGV[0] && ($ARGV[0] =~ /remove/ || $ARGV[0] =~ /upgrade/)) { + if (-l "/usr/doc/linux-image-$version") { + unlink "/usr/doc/linux-image-$version"; + } +} + +# Ignore all invocations uxcept when called on to remove +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /remove/) ; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz";} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz";} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz";} # Default + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +#check to see if we are trying to remove a running kernel +# if so we abort right now. +chop($running=`uname -r`); +if ($running eq $version) { + print STDERR "WARN: Proceeding with removing running kernel image.\n"; +} + +#Now, they have an alternate kernel which they are currently running + +# This is just us being nice to lilo users. + +chdir("/") or die "could not chdir to /:$!\n"; + +if (-f "/etc/$loader.conf") { #I know, could be a link, but .. + open (LILO, "/etc/$loader.conf") || &success(); # this is not critical + while () { + chop; + s/\#.*//; # nix the comments + next unless /^\s*image\s*=\s(\S+)/o; + $image = $1; + if ($image && -e $image) { + while (defined($image) && -l $image) { + $image = readlink ($image); + } + if (defined($image) && -e $image) { + $WouldInvalidate |= $image =~ /$kimage-$version/; + } + else { + &success(); # invalid $loader.conf file + } + } + else { + &success(); # invalid $loader.conf file + } + } + close (LILO); + if ($WouldInvalidate) { + print STFERR "WARN: Proceeding with removing running kernel image.\n"; + &success(); + } +} + + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$prerm_hook") { + &run_hook("prerm", $prerm_hook); +} +if (-d "/etc/kernel/prerm.d") { + print STDERR "Examining /etc/kernel/prerm.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version /etc/kernel/prerm.d") && + die "Failed to process /etc/kernel/prerm.d"; +} +if (-d "/etc/kernel/prerm.d/$version") { + print STDERR "Examining /etc/kernel/prerm.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version " . + "/etc/kernel/prerm.d/$version") && + die "Failed to process /etc/kernel/prerm.d/$version"; +} + +sub success () { + -f "/lib/modules/$version/modules.dep" && + unlink "/lib/modules/$version/modules.dep"; + exit 0; +} + + + +&success(); +exit 0; +__END__ + + + + + --- linux-source-2.6.22-2.6.22.orig/debian/control-scripts/headers-postinst +++ linux-source-2.6.22-2.6.22/debian/control-scripts/headers-postinst @@ -0,0 +1,132 @@ +#!/usr/bin/perl +# -*- Mode: Cperl -*- +# debian.postinst --- +# Author : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# Created On : Sat Apr 27 05:42:43 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:20:22 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 45 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# +# arch-tag: 1c716174-2f0a-476d-a626-a1322e62503a +# + + +$|=1; + +# Predefined values: +my $version = "=V"; +my $kimage = "=K"; +my $package_name = "linux-image-$version"; + + +# Ignore all invocations uxcept when called on to configure. +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /configure/); + +#known variables +my $image_dest = "/"; +my $realimageloc = "/boot/"; +my $silent_modules = ''; +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +my $architecture; +chomp($architecture = `dpkg --print-installation-architecture`); +$architecture = "parisc" if $architecture eq "hppa"; +$architecture = "mips" if $architecture eq "mipsel"; +$architecture = "x86_64" if $architecture eq "amd64"; + +chdir '/usr/src' or die "Could not chdir to /usr/src:$!"; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $header_postinst_hook = "$1" if /^\s*header_postinst_hook\s*=\s*(\S+)/ig; + } + close CONF; + } +} + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if (-x "$header_postinst_hook") { + &run_hook("postinst", $header_postinst_hook); +} + +if (-d "/etc/kernel/header_postinst.d") { + print STDERR "Examining /etc/kernel/header_postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d") && + die "Failed to process /etc/kernel/header_postinst.d"; +} + +if (-d "/etc/kernel/header_postinst.d/$version") { + print STDERR "Examining /etc/kernel/header_postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d/$version") && + die "Failed to process /etc/kernel/header_postinst.d/$version"; +} + +exit 0; + +__END__ --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.mckinley +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.mckinley @@ -0,0 +1,6 @@ +supported="Itanium II SMP" +target="Geared toward desktop or server systems." +desc="Itanium II SMP" +bootloader="elilo (>= 3.6-1)" +provides="rhcs-modules2-1, ivtv-modules" +arch="ia64" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.powerpc64-smp +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.powerpc64-smp @@ -0,0 +1,6 @@ +supported="64-bit PowerPC SMP" +target="Geared toward desktop or server systems." +desc="64-bit PowerPC SMP" +bootloader="yaboot" +provides="rhcs-modules2-1, ivtv-modules" +arch="powerpc" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/flavour-control-debug.stub +++ linux-source-2.6.22-2.6.22/debian/control.d/flavour-control-debug.stub @@ -0,0 +1,26 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-debug-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version PKGVER on DESC + This package provides a kernel debug image for version PKGVER on + DESC. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.powerpc-smp +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.powerpc-smp @@ -0,0 +1,6 @@ +supported="32-bit PowerPC SMP" +target="Geared toward desktop or server systems." +desc="32-bit PowerPC SMP" +bootloader="yaboot" +provides="rhcs-modules2-1, ivtv-modules" +arch="powerpc" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.virtual +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.virtual @@ -0,0 +1,7 @@ +arch="i386" +supported="Virtual" +target="Geared toward virtualised hardware." +desc="x86" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, rhcs-modules2-1" +do_debug="Yes" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.generic +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.generic @@ -0,0 +1,7 @@ +arch="i386 amd64" +supported="Generic" +target="Geared toward desktop systems." +desc="x86/x86_64" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, rhcs-modules2-1, ivtv-modules" +do_debug="Yes" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.hppa64 +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.hppa64 @@ -0,0 +1,6 @@ +supported="64-bit HP PA-RISC SMP" +target="Geared toward desktop or server systems." +desc="64-bit HP PA-RISC SMP" +bootloader="palo" +provides="rhcs-modules2-1" +arch="hppa" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.hppa32 +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.hppa32 @@ -0,0 +1,6 @@ +supported="32-bit HP PA-RISC SMP" +target="Geared toward desktop or server systems." +desc="32-bit HP PA-RISC SMP" +bootloader="palo" +provides="rhcs-modules2-1" +arch="hppa" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.sparc64 +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.sparc64 @@ -0,0 +1,6 @@ +supported="64-bit UltraSPARC" +target="Geared toward desktop or server systems." +desc="64-bit UltraSPARC" +bootloader="silo" +provides="rhcs-modules2-1, ivtv-modules" +arch="sparc" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.itanium +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.itanium @@ -0,0 +1,6 @@ +supported="Itanium SMP" +target="Geared toward desktop or server systems." +desc="Itanium SMP" +bootloader="elilo (>= 3.6-1)" +provides="rhcs-modules2-1, ivtv-modules" +arch="ia64" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.sparc64-smp +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.sparc64-smp @@ -0,0 +1,6 @@ +supported="64-bit UltraSPARC SMP" +target="Geared toward desktop or server systems." +desc="64-bit UltraSPARC SMP" +bootloader="silo" +provides="rhcs-modules2-1, ivtv-modules" +arch="sparc" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.386 +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.386 @@ -0,0 +1,7 @@ +supported="Alternate x86 (486 and better)" +target="Geared toward desktop systems." +desc="i386" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, ivtv-modules" +arch=i386 +do_debug="Yes" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.powerpc +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.powerpc @@ -0,0 +1,6 @@ +supported="32-bit PowerPC" +target="Geared toward desktop or server systems." +desc="32-bit PowerPC" +bootloader="yaboot" +provides="rhcs-modules2-1, ivtv-modules" +arch="powerpc" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/vars.server +++ linux-source-2.6.22-2.6.22/debian/control.d/vars.server @@ -0,0 +1,7 @@ +arch="i386 amd64" +supported="Server" +target="Geared toward server systems." +desc="x86/x86_64" +bootloader="lilo (>= 19.1) | grub" +provides="rhcs-modules2-1, kvm-api-4, ivtv-modules" +do_debug="Yes" --- linux-source-2.6.22-2.6.22.orig/debian/control.d/flavour-control.stub +++ linux-source-2.6.22-2.6.22/debian/control.d/flavour-control.stub @@ -0,0 +1,51 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: SECTION_IMAGE +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, =PROVIDES= +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: BOOTLOADER +Suggests: fdutils, linux-doc-PKGVER | linux-source-PKGVER +Description: Linux kernel image for version PKGVER on DESC + This package contains the Linux kernel image for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: SECTION_HEADERS +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-PKGVER-ABINUM, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version PKGVER on DESC + This package provides kernel header files for version PKGVER on + DESC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details. --- linux-source-2.6.22-2.6.22.orig/debian/control.stub +++ linux-source-2.6.22-2.6.22/debian/control.stub @@ -0,0 +1,880 @@ +Source: linux-source-2.6.22 +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), gcc-4.1-hppa64 [hppa], binutils-hppa64 [hppa], device-tree-compiler [powerpc] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils + +Package: linux-kernel-devel +Architecture: all +Section: devel +Priority: optional +Depends: build-essential, git-core, gitk, rsync, curl, openssh-client, debhelper, kernel-package, kernel-wedge +Description: Linux kernel hacking dependencies + This is a dummy package that will install all possible packages + required to hack comfortably on the kernel. + +Package: linux-source-2.6.22 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.22 with Ubuntu patches + This package provides the source code for the Linux kernel version 2.6.22. + . + You may configure the kernel to your setup by typing "make config" and + following instructions, but you could get ncursesX.X-dev and try "make + menuconfig" for a jazzier, and easier to use interface. There are options + to use QT or GNOME based configuration interfaces, but they need + additional packages to be installed. Also, please read the detailed + documentation in the file + /usr/share/doc/linux-source-2.6.22/README.headers.gz. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.22 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.22 + This package provides the various readme's in the 2.6.22 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.22/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.22-15 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.22 + This package provides kernel header files for version 2.6.22, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details + +Package: linux-libc-dev +Architecture: amd64 i386 powerpc sparc ia64 hppa lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1) +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6) +Provides: linux-kernel-headers +Conflicts: linux-kernel-headers +Replaces: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. + +Package: linux-image-2.6.22-15-386 +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on i386 + This package contains the Linux kernel image for version 2.6.22 on + i386. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Alternate x86 (486 and better) processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-386 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-386 +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on i386 + This package provides kernel header files for version 2.6.22 on + i386. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-386 +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on i386 + This package provides a kernel debug image for version 2.6.22 on + i386. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.22 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86/x86_64 + This package provides kernel header files for version 2.6.22 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86/x86_64 + This package provides a kernel debug image for version 2.6.22 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-hppa32 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.22 on + 32-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa32 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-hppa32 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.22 on + 32-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-hppa64 +Architecture: hppa +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: palo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit HP PA-RISC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit HP PA-RISC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit HP PA-RISC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-hppa64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-hppa64 +Architecture: hppa +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit HP PA-RISC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit HP PA-RISC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-itanium +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Itanium SMP + This package contains the Linux kernel image for version 2.6.22 on + Itanium SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-itanium meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-itanium +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Itanium SMP + This package provides kernel header files for version 2.6.22 on + Itanium SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-mckinley +Architecture: ia64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: elilo (>= 3.6-1) +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Itanium II SMP + This package contains the Linux kernel image for version 2.6.22 on + Itanium II SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Itanium II SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-mckinley meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-mckinley +Architecture: ia64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Itanium II SMP + This package provides kernel header files for version 2.6.22 on + Itanium II SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit PowerPC + This package contains the Linux kernel image for version 2.6.22 on + 32-bit PowerPC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit PowerPC + This package provides kernel header files for version 2.6.22 on + 32-bit PowerPC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc64-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc64-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit PowerPC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-powerpc-smp +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 32-bit PowerPC SMP + This package contains the Linux kernel image for version 2.6.22 on + 32-bit PowerPC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 32-bit PowerPC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-powerpc-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-powerpc-smp +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 32-bit PowerPC SMP + This package provides kernel header files for version 2.6.22 on + 32-bit PowerPC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, kvm-api-4, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.22 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86/x86_64 + This package provides kernel header files for version 2.6.22 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86/x86_64 + This package provides a kernel debug image for version 2.6.22 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-sparc64 +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit UltraSPARC + This package contains the Linux kernel image for version 2.6.22 on + 64-bit UltraSPARC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-sparc64 +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit UltraSPARC + This package provides kernel header files for version 2.6.22 on + 64-bit UltraSPARC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-sparc64-smp +Architecture: sparc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1, ivtv-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: silo +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on 64-bit UltraSPARC SMP + This package contains the Linux kernel image for version 2.6.22 on + 64-bit UltraSPARC SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports 64-bit UltraSPARC SMP processors. + . + Geared toward desktop or server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-sparc64-smp meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-sparc64-smp +Architecture: sparc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on 64-bit UltraSPARC SMP + This package provides kernel header files for version 2.6.22 on + 64-bit UltraSPARC SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-virtual +Architecture: i386 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on x86 + This package contains the Linux kernel image for version 2.6.22 on + x86. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtualised hardware. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-virtual +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on x86 + This package provides kernel header files for version 2.6.22 on + x86. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-debug-2.6.22-15-virtual +Architecture: i386 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.22 on x86 + This package provides a kernel debug image for version 2.6.22 on + x86. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. + +Package: linux-image-2.6.22-15-xen +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on This kernel can be used for Xen dom0 and domU + This package contains the Linux kernel image for version 2.6.22 on + This kernel can be used for Xen dom0 and domU. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Xen domO/domU + . + You likely do not want to install this package directly. Instead, install + the linux-xen meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-xen +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on This kernel can be used for Xen dom0 and domU + This package provides kernel header files for version 2.6.22 on + This kernel can be used for Xen dom0 and domU. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-rt +Architecture: i386 amd64 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on RT kernel + This package contains the Linux kernel image for version 2.6.22 on + RT kernel. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Ingo Molnar's full real time preemption patch (2.6.22.1-rt9) + . + You likely do not want to install this package directly. Instead, install + the linux-rt meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-rt +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on RT kernel + This package provides kernel header files for version 2.6.22 on + RT kernel. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-ume +Architecture: i386 +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-ume meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-ume +Architecture: i386 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-cell +Architecture: powerpc +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: yaboot +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on PowerPC Cell + This package contains the Linux kernel image for version 2.6.22 on + PowerPC Cell. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports PowerPC Cell processors. + . + Supports PowerPC Cell (Including PS3) + . + You likely do not want to install this package directly. Instead, install + the linux-cell meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-cell +Architecture: powerpc +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on PowerPC Cell + This package provides kernel header files for version 2.6.22 on + PowerPC Cell. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-lpiacompat +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded-x86 compat edition + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpiacompat meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-lpiacompat +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded-x86 compat edition + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded-x86 compat edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. + +Package: linux-image-2.6.22-15-lpia +Architecture: lpia +Section: universe/base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, rhcs-modules2-1 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.2.1-0ubuntu1) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.22 | linux-source-2.6.22 +Description: Linux kernel image for version 2.6.22 on Ubuntu Moblie and Embedded LPIA edition + This package contains the Linux kernel image for version 2.6.22 on + Ubuntu Moblie and Embedded LPIA edition. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports UME processors. + . + UME kernel + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.22-15-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.22-15, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.22 on Ubuntu Moblie and Embedded LPIA edition + This package provides kernel header files for version 2.6.22 on + Ubuntu Moblie and Embedded LPIA edition. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.22-15/debian.README.gz for details. --- linux-source-2.6.22-2.6.22.orig/debian/changelog +++ linux-source-2.6.22-2.6.22/debian/changelog @@ -0,0 +1,2962 @@ +linux-source-2.6.22 (2.6.22-15.58) gutsy-security; urgency=low + + [Stefan Bader] + + * mm: Fix zero length segment loop + - LP: #249340 + follow-up for CVE-2008-0598 + + [Upstream Kernel Changes] + + * Fix compiler warning on 64-bit + follow-up for CVE-2008-1673 + * netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP + follow-up for CVE-2008-1673 + + -- Stefan Bader Thu, 14 Aug 2008 10:11:31 -0400 + +linux-source-2.6.22 (2.6.22-15.57) gutsy-security; urgency=low + + [Upstream Kernel Changes] + + * (CVE-2008-2812) TTY: fix for tty operations bugs + * (CVE-2008-3272) sound: ensure device number is valid in + snd_seq_oss_synth_make_info + * (CVE-2008-3275) vfs: fix lookup on deleted directory + + -- Tim Gardner Sat, 02 Aug 2008 09:13:56 -0600 + +linux-source-2.6.22 (2.6.22-15.56) gutsy-security; urgency=low + + * Fix hppa FTBS by ignoring hppa ABI check. The last successful hppa + upload was -14.52. + + -- Tim Gardner Fri, 11 Jul 2008 10:40:39 -0600 + +linux-source-2.6.22 (2.6.22-15.55) gutsy-security; urgency=low + + [Upstream Kernel Changes] + + * (CVE-2008-1673) asn1: additional sanity checking during BER decoding + * (CVE-2008-2136) sit: Add missing kfree_skb() on pskb_may_pull() failure. + * (CVE-2008-2137) sparc: Fix mmap VA span checking. + * (CVE-2008-2148) vfs: fix permission checking in sys_utimensat + * (CVE-2008-2358) dccp: return -EINVAL on invalid feature length + * (CVE-2008-1615) x86_64: fix CS corruption on iret + * (CVE-2008-2826) sctp: Make sure N * sizeof(union sctp_addr) does not overflow. + * (CVE-2008-0598) mm: trim more holes + + -- Tim Gardner Tue, 01 Jul 2008 10:30:32 -0600 + +linux-source-2.6.22 (2.6.22-15.54) gutsy-security; urgency=low + + [Colin Ian King] + + * usb-storage: always set the allow_restart flag + - LP: #193154 + + [Upstream Kernel Changes] + + * [IA64] Fix unaligned handler for floating point instructions with base + update + * CVE-2007-6694: [POWERPC] CHRP: Fix possible NULL pointer dereference + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669) + * Fix dnotify/close race (CVE-2008-1375) + * [TCP]: secure_tcp_sequence_number() should not use a too fast clock + * hrtimer: check relative timeouts for overflow + * netdrvr: natsemi: Fix device removal bug + + -- Ben Collins Mon, 19 May 2008 23:03:41 +0000 + +linux-source-2.6.22 (2.6.22-14.53) gutsy; urgency=low + + [Upstream Kernel Changes] + + * knfsd: Validate filehandle type in fsid_source + * NFS: Fix a potential file corruption issue when writing + * knfsd: fix spurious EINVAL errors on first access of new filesystem + * NFS: Fix nfs_reval_fsid() + * NFSv2/v3: Fix a memory leak when using -onolock + * NFS: Fix an Oops in encode_lookup() + * knfsd: query filesystem for NFSv4 getattr of FATTR4_MAXNAME + * [CIFS] Fix buffer overflow if server sends corrupt response to small + + -- Stefan Bader Wed, 12 Mar 2008 15:14:40 -0400 + +linux-source-2.6.22 (2.6.22-14.52) gutsy-security; urgency=low + + [Tim Gardner] + + * splice: fix user pointer access in get_iovec_page_array() + (CVE-2008-0600) + - LP: #190587 + + -- Tim Gardner Mon, 11 Feb 2008 10:01:17 -0700 + +linux-source-2.6.22 (2.6.22-14.51) gutsy-security; urgency=low + + [Amit Kucheria] + + * Poulsbo: Mass update of all patches from moblin repo + * Update config.lpia to reflect new patches + * [sata_sil][sata->ide-bridg] failed to set xfermode + - LP: #153096 + * Poulsbo: remove extra patch + + [Kees Cook] + + * fix NFSv4 client mount regression + - LP: #164231 + + [Tim Gardner] + + * Support of new AMD PowerNow! (family 0x11 and beyond) + - LP: #185649 + + [Upstream Kernel Changes] + + * minixfs: limit minixfs printks on corrupted dir i_size (CVE-2006-6058) + * [JFFS2] Fix ACL vs. mode handling. (CVE-2007-4849) + * [IEEE80211]: avoid integer underflow for runt rx frames (CVE-2007-4997) + * [TCP]: Make sure write_queue_from does not begin with NULL ptr + (CVE-2007-5501) + * wait_task_stopped: Check p->exit_state instead of TASK_TRACED + (CVE-2007-5500) + * fix DLM regression + * CVE-2008-0001: Use access mode instead of open flags to determine + needed permissions + * hrtimers: avoid overflow for large relative timeouts (CVE-2007-5966) + * isdn: avoid copying overly-long strings (CVE-2007-6063) + * I4L: fix isdn_ioctl memory overrun vulnerability (CVE-2007-6151) + * vfs: coredumping fix (CVE-2007-6206) + * tmpfs: restore missing clear_highpage (CVE-2007-6417) + * [UBUNTU] fs/dlm: Fix regression introduced with last security fix. + + -- Tim Gardner Mon, 28 Jan 2008 13:46:21 -0700 + +linux-source-2.6.22 (2.6.22-14.47) gutsy-security; urgency=low + + [Security] + + * wait_task_stopped: Check p->exit_state instead of TASK_TRACED + (CVE-2007-5500) + * [TCP]: Make sure write_queue_from does not begin with NULL ptr + (CVE-2007-5501) + * [IEEE80211]: avoid integer underflow for runt rx frames (CVE-2007-4997) + * [JFFS2] Fix ACL vs. mode handling. (CVE-2007-4849) + * minixfs: limit minixfs printks on corrupted dir i_size (CVE-2006-6058) + * NFS: Fix the mount regression + + [Fabio Massimo Di Nitto] + + * fix DLM regression + + [Tim Gardner] + + * linux-image postinst matches header_postinst_hook for postinst_hook + incorrectly + - LP: #125816 + + [Upstream Kernel Changes] + + * [SPARC64]: Fix bugs in SYSV IPC handling in 64-bit processes. + * [SPARC64]: Fix register usage in xor_raid_4(). + * [NIU]: Fix write past end of array in niu_pci_probe_sprom(). + * [NIU]: getting rid of __ucmpdi2 in niu.o + * [SPARC64]: Do not use alloc_bootmem*low(). + * [SPARC64]: Fix bogus '&' conditinal in set_rtc_mmss(). + * [FUTEX]: Fix address computation in compat code. + * [NIU]: Fix link LED handling. + * [SPARC64]: Fix memory controller register access when non-SMP. + * [SPARC64]: Fix endless loop in cheetah_xcall_deliver(). + * [SPARC64]: Fix two kernel linear mapping setup bugs. + + -- Phillip Lougher Thu, 13 Dec 2007 23:57:58 +0000 + +linux-source-2.6.22 (2.6.22-14.46) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix bugs in SYSV IPC handling in 64-bit processes. + + -- Kyle McMartin Sun, 14 Oct 2007 20:30:09 +0000 + +linux-source-2.6.22 (2.6.22-14.45) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix register usage in xor_raid_4(). + + -- Kyle McMartin Sun, 14 Oct 2007 12:34:44 -0400 + +linux-source-2.6.22 (2.6.22-14.44) gutsy; urgency=low + + [Kyle McMartin] + + * Revert "sparc wants ehci built in" + + [Upstream Kernel Changes] + + * Revert "[PATCH]: Gutsy OHCI hang workaround for Huron" + * [USB]: Serialize EHCI CF initialization. + + -- Kyle McMartin Sun, 14 Oct 2007 16:25:51 +0000 + +linux-source-2.6.22 (2.6.22-14.43) gutsy; urgency=low + + [Kyle McMartin] + + * sparc wants ehci built in + + -- Kyle McMartin Tue, 09 Oct 2007 20:07:58 +0000 + +linux-source-2.6.22 (2.6.22-14.42) gutsy; urgency=low + + [Kyle McMartin] + + * fix up module-check to bail early if asked to ignore modules + * disable kernel DRM on lpia (we provide one in lum) + - LP: #145168 + * add ignore for ia64 abi too + + [Upstream Kernel Changes] + + * [NIU]: Use netif_msg_*(). + * [NIU]: Use pr_info(). + * [NIU]: Remove redundant BUILD_BUG_ON() in __niu_wait_bits_clear(). + * [NIU]: Remove BUG_ON() NULL pointer checks. + * [NIU]: Use dev_err(). + * [NIU]: Fix x86_64 build failure. + * [NIU]: Use linux/io.h instead of asm/io.h + * [NIU]: Fix some checkpatch caught coding style issues. + * [NIU]: Fix shadowed local variables. + * [NIU]: Fix locking errors in link_status_10g(). + * [NIU]: Document a few magic constants using comments. + * [NIU]: MII phy handling fixes. + * [NIU]: Make sure link_up status is set to something in + link_status_{1,10}g(). + * [PATCH]: Gutsy OHCI hang workaround for Huron + + -- Kyle McMartin Tue, 09 Oct 2007 17:25:06 +0000 + +linux-source-2.6.22 (2.6.22-14.41) gutsy; urgency=low + + [Ben Collins] + + * ubuntu/d-i: Add niu to nic-modules + + [Kyle McMartin] + + * vesafb is not for ia64 + * remove CONFIG_NIU from places it shouldn't be + * fix orinoco_cs oops + - LP: #149997 + + [Upstream Kernel Changes] + + * [SPARC64]: Allow userspace to get at the machine description. + * [SPARC64]: Niagara-2 optimized copies. + * [SPARC64]: Do not touch %tick_cmpr on sun4v cpus. + * [SPARC64]: SMP trampoline needs to avoid %tick_cmpr on sun4v too. + * [SPARC64]: Create a HWCAP_SPARC_N2 and report it to userspace on + Niagara-2. + * [MATH-EMU]: Fix underflow exception reporting. + * [SPARC64]: Need to clobber global reg vars in switch_to(). + * [MATH]: Fix typo in FP_TRAPPING_EXCEPTIONS default setting. + * [SUNVDC]: Use slice 0xff on VD_DISK_TYPE_DISK. + * [SPARC64]: Fix type and constant sizes wrt. sun4u IMAP/ICLR handling. + * [SPARC64]: Enable MSI on sun4u Fire PCI-E controllers. + * [SPARC64]: Fix several bugs in MSI handling. + * [SPARC64]: Fix booting on V100 systems. + * [SPARC64]: Fix lockdep, particularly on SMP. + * [SPARC64]: Warn user if cpu is ignored. + * [SUNSAB]: Fix several bugs. + * [SUNSAB]: Fix broken SYSRQ. + * [SPARC64]: Fix missing load-twin usage in Niagara-1 memcpy. + * [SPARC64]: Don't use in/local regs for ldx/stx data in N1 memcpy. + * [SPARC64]: Fix domain-services port probing. + * [SPARC64]: VIO device addition log message level is too high. + * [SPARC64]: check fork_idle() error + * [SPARC64]: Fix 'niu' complex IRQ probing. + * [NIU]: Add Sun Neptune ethernet driver. + + -- Kyle McMartin Tue, 09 Oct 2007 00:38:16 +0000 + +linux-source-2.6.22 (2.6.22-13.40) gutsy; urgency=low + + [Amit Kucheria] + + * Enable CONFIG_VM86 for LPIA + - LP: #146311 + * Update configuration files + * Disable MSI by default + * Add mmconf documentation + * Update configuration files + + [Bartlomiej Zolnierkiewicz] + + * ide-disk: workaround for buggy HPA support on ST340823A (take 3) + - LP: #26119 + + [Ben Collins] + + * ubuntu/cell: Fixup ps3 related modules for d-i, enable RTAS console + * ubuntu/cell: Enable CELLEB and related modules (pata_scc) + * ubuntu/cell: Move ps3rom to storage-core. Also use spidernet, not + spider_net. + * ubuntu/cell: Set PS3_MANAGER=y + * ubuntu: Set NR_CPUS=256 for sparc64-smp + + [Chuck Short] + + * [USB] USB] Support for MediaTek MT6227 in cdc-acm. + - LP: #134123 + * [XEN] Fix xen vif create with more than 14 guests. + - LP: #14486 + + [Jorge Juan Chico] + + * ide: ST320413A has the same problem as ST340823A + - LP: #26119 + + [Kyle McMartin] + + * fix -rt build + * fix ia32entry-xen.S for CVE-2007-4573 + * fix build when CONFIG_PCI_MSI is not set + + [Matthew Garrett] + + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * Don't lose appletouch button release events + * Fix build with appletouch change + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + + [Steffen Klassert] + + * 3c59x: fix duplex configuration + - LP: #94186 + + [Thomas Gleixner] + + * clockevents: remove the suspend/resume workaround^Wthinko + + [Tim Gardner] + + * orinoco_cs.ko missing + - LP: #125832 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * acpi_scan_rsdp() breaks some PCs by not honouring ACPI specification + - LP: #144336 + * VIA southbridge Intel id missing + - LP: #128289 + * Add T-Sinus 111card to hostap_cs driver to be able to upload firmware + - LP: #132466 + * RTL8111 PCI Express Gigabit driver r8169 big files produce slow file + transfer + - LP: #114171 + * Guest OS does not recognize a lun with non zero target id on Vmware ESX + Server + - LP: #140761 + * Modualrize vesafb + - LP: #139505 + * Nikon cameras need support in unusual_devs.h + - LP: #134477 + * agp for i830m broken in gutsy + - LP: #139767 + * hdaps: Added support for Thinkpad T61 + - LP: #147383 + * xen: Update config for i386 + - LP: #139047 + * xen: resync for amd64 + - LP: #139047 + * ide-disk: workaround for buggy HPA support on ST340823A (take 4) + - LP: #26119 + + [Upstream Kernel Changes] + + * Convert snd-page-alloc proc file to use seq_file (CVE-2007-4571) + * Linux 2.6.22.8 + * ACPI: disable lower idle C-states across suspend/resume + * V4L: ivtv: fix VIDIOC_S_FBUF: new OSD values were never set + * DVB: get_dvb_firmware: update script for new location of sp8870 + firmware + * DVB: get_dvb_firmware: update script for new location of tda10046 + firmware + * DVB: b2c2-flexcop: fix Airstar HD5000 tuning regression + * setpgid(child) fails if the child was forked by sub-thread + * sigqueue_free: fix the race with collect_signal() + * kconfig: oldconfig shall not set symbols if it does not need to + * MTD: Makefile fix for mtdsuper + * USB: fix linked list insertion bugfix for usb core + * ACPI: Validate XSDT, use RSDT if XSDT fails + * POWERPC: Flush registers to proper task context + * 3w-9xxx: Fix dma mask setting + * MTD: Initialise s_flags in get_sb_mtd_aux() + * JFFS2: fix write deadlock regression + * V4L: cx88: Avoid a NULL pointer dereference during mpeg_open() + * hwmon: End of I/O region off-by-one + * Fix debug regression in video/pwc + * splice: fix direct splice error handling + * rpc: fix garbage in printk in svc_tcp_accept() + * disable sys_timerfd() + * afs: mntput called before dput + * Fix DAC960 driver on machines which don't support 64-bit DMA + * Fix "Fix DAC960 driver on machines which don't support 64-bit DMA" + * firewire: fw-ohci: ignore failure of pci_set_power_state (fix suspend + regression) + * futex_compat: fix list traversal bugs + * Leases can be hidden by flocks + * ext34: ensure do_split leaves enough free space in both blocks + * nfs: fix oops re sysctls and V4 support + * dir_index: error out instead of BUG on corrupt dx dirs + * ieee1394: ohci1394: fix initialization if built non-modular + * Correctly close old nfsd/lockd sockets. + * Fix race with shared tag queue maps + * crypto: blkcipher_get_spot() handling of buffer at end of page + * fix realtek phy id in forcedeth + * Fix decnet device address listing. + * Fix device address listing for ipv4. + * Fix inet_diag OOPS. + * Fix IPV6 append OOPS. + * Fix IPSEC AH4 options handling + * Fix ipv6 double-sock-release with MSG_CONFIRM + * Fix IPV6 DAD handling + * Fix ipv6 source address handling. + * Fix oops in vlan and bridging code + * Fix tc_ematch kbuild + * Handle snd_una in tcp_cwnd_down() + * Fix TCP DSACK cwnd handling + * Fix datagram recvmsg NULL iov handling regression. + * Fix pktgen src_mac handling. + * Fix sparc64 v100 platform booting. + * bcm43xx: Fix cancellation of work queue crashes + * Linux 2.6.22.9 + * usb: serial/pl2303: support for BenQ Siemens Mobile Phone EF81 + * pata_it821x: fix lost interrupt with atapi devices + * i915: make vbl interrupts work properly on i965g/gm hw. + + -- Kyle McMartin Thu, 04 Oct 2007 13:57:53 +0000 + +linux-source-2.6.22 (2.6.22-12.39) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Re-order deps so that binary-custom is done before + binary-udebs. Fixes ppc build + + [Upstream Kernel Changes] + + * x86_64: Zero extend all registers after ptrace in 32bit entry path. + * Linux 2.6.22.7 + + -- Ben Collins Sun, 23 Sep 2007 11:05:32 -0400 + +linux-source-2.6.22 (2.6.22-12.38) gutsy; urgency=low + + [Kyle McMartin] + + * add -12 abi files + * update getabis for new flavours + + -- Kyle McMartin Fri, 21 Sep 2007 13:35:49 -0400 + +linux-source-2.6.22 (2.6.22-12.37) gutsy; urgency=low + + [Kyle McMartin] + + * enable d-i for cell flavour + * ignore ABI check on all hppa flavours + + -- Kyle McMartin Fri, 21 Sep 2007 11:28:34 -0400 + +linux-source-2.6.22 (2.6.22-12.36) gutsy; urgency=low + + [Ben Collins] + + * ABI bump due to LED support being enabled. + + [Kyle McMartin] + + * fix memory leak in psparse.c + - Bug introduced in previous commit to acpi + + [Upstream Kernel Changes] + + * Ubuntu: Allocate acpi_devices structure rather than leaving it on the + stack. + * ipw2100: Fix `iwpriv set_power` error + * Fix ipw2200 set wrong power parameter causing firmware error + * [SCSI] Fix async scanning double-add problems + - LP: #110997 + + -- Ben Collins Thu, 20 Sep 2007 11:34:52 -0400 + +linux-source-2.6.22 (2.6.22-11.34) gutsy; urgency=low + + [Alan Stern] + + * USB: disable autosuspend by default for non-hubs + - LP: #85488 + + [Ben Collins] + + * ubuntu: Enable LEDS_TRIGGERS and related options + - Needed for iwlwifi + * ubuntu: Add real ABI files for virtual flavour + * ubuntu: Re-enable missing CONFIG_SERPENT for hppa64 + - Noticed by Lamont + * ubuntu: Add linux-headers postinst to handle hooks + - LP: #125816 + * ubuntu: Add support for /etc/kernel/headers_postinst.d/ to + headers-postinst + - LP: #120049 + * cell: Add binary-custom flavour "cell" to support ps3 + + [Mattia Dongili] + + * sony-laptop: restore the last user requested brightness level on + resume. + - LP: #117331 + + [Tejun Heo] + + * ata_piix: fix suspend/resume for some TOSHIBA laptops + - LP: #139045 + * PCI: export __pci_reenable_device() + - needed for ata_piix change + + [Tim Gardner] + + * Enable Sierra Wireless MC8775 0x6813 + - LP: #131167 + + [Zhang Rui] + + * ACPI: work around duplicate name "VID" problem on T61 + - Noted by mjg59 + + -- Ben Collins Sun, 16 Sep 2007 22:31:47 -0400 + +linux-source-2.6.22 (2.6.22-11.33) gutsy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to rt9 + * rt: Update configuration files + + [Ben Collins] + + * ubuntu: Enable A100 driver + - LP: #138632 + * libata: Default to hpa being overridden + + [Chuck Short] + + * [HDAPS] Add support for Thinkpad R61. + * [LIBATA] Add more hard drives to blacklist. + * [USB] Added support for Sprint Pantech PX-500. + * [XEN] No really enable amd64. + * [XEN] Fix amd64 yet again. + + [Matthew Garrett] + + * alter default behaviour of ACPI video module + * Add infrastructure for notification on ACPI method execution + * Get thinkpad_acpi to send notifications on CMOS updates + * Add support to libata-acpi for acpi-based bay hotplug + + [Phillip Lougher] + + * Add kernel flavour optimised for virtualised environments + * Change abi-check script to check for $flavour.ignore in previous abi + * Disable abi and module check for virtual flavour + + [Richard Hughes] + + * Refresh laptop lid status on resume + + [Upstream Kernel Changes] + + * [pata_marvell]: Add more identifiers + + -- Ben Collins Sun, 16 Sep 2007 22:13:08 -0400 + +linux-source-2.6.22 (2.6.22-11.32) gutsy; urgency=low + + [Amit Kucheria] + + * Build system: Allow custom builds to comprise multiple patches + * Move UME to a Custom build and add first setup of thermal framework + + [Ben Collins] + + * ubuntu: Enable CONFIG_BLK_DEV_IO_TRACE + * bcm203x: Fix firmware loading + - LP: #85247 + * ubuntu: mtd changes caused module renaming. Ignore + * rt: Do not patch top level Makefile for SUBLEVEL. Will always end up + breaking + + [Chuck Short] + + * [USB] Unusual Device support for Gold MP3 Player Energy + - LP: #125250 + * [SIERRA] Adds support for Onda H600 ZTE MF330 + - LP: #129433 + * [HDAPS] Add Thinkpad T61P to whitelist. + - LP: #133636 + * [USB] Add support for Toshiba (Novatel Wireless) HSDPA for M400. + - LP: #133650 + + [Kyle McMartin] + + * apparmor 10.3 hooks + * unionfs 2.1 hooks + * nuke UNION_FS stuff from fs/{Kconfig,Makefile} + + [Tim Gardner] + + * Paravirt-ops I/O hypercalls + * Fix lazy vmalloc bug for Gutsy + * bluetooth headset patch + - LP: #130870 + * Add the PCI ID of this ICH4 in list of laptops that use short cables. + * v2.6.22.5 merge + * Update Xen config options. + - LP: #132726 + * Remove mtd modules from ABI + * Support parallel= in DEB_BUILD_OPTIONS + - LP: #136426 + + [Upstream Kernel Changes] + + * hwmon: fix w83781d temp sensor type setting + * hwmon: (smsc47m1) restore missing name attribute + * sky2: restore workarounds for lost interrupts + * sky2: carrier management + * sky2: check for more work before leaving NAPI + * sky2: check drop truncated packets + * revert "x86, serial: convert legacy COM ports to platform devices" + * ACPICA: Fixed possible corruption of global GPE list + * ACPICA: Clear reserved fields for incoming ACPI 1.0 FADTs + * AVR32: Fix atomic_add_unless() and atomic_sub_unless() + * r8169: avoid needless NAPI poll scheduling + * forcedeth: fix random hang in forcedeth driver when using netconsole + * libata: add ATI SB700 device IDs to AHCI driver + * Hibernation: do not try to mark invalid PFNs as nosave + * i386: allow debuggers to access the vsyscall page with compat vDSO + * x86_64: Check for .cfi_rel_offset in CFI probe + * x86_64: Change PMDS invocation to single macro + * i386: Handle P6s without performance counters in nmi watchdog + * i386: Fix double fault handler + * JFFS2 locking regression fix. + * [Input]: appletouch - improve powersaving for Geyser3 devices + * [Input]: add driver for Fujitsu serial touchscreens + * [sdhci]: add support to ENE-CB714 + * v2.6.22.5 + * [MTD] Makefile fix for mtdsuper + * ocfs2: Fix bad source start calculation during kernel writes + * NET: Share correct feature code between bridging and bonding + * sky2: don't clear phy power bits + * uml: fix previous request size limit fix + * i386: fix lazy mode vmalloc synchronization for paravirt + * signalfd: fix interaction with posix-timers + * signalfd: make it group-wide, fix posix-timers scheduling + * DCCP: Fix DCCP GFP_KERNEL allocation in atomic context + * IPV6: Fix kernel panic while send SCTP data with IP fragments + * IPv6: Invalid semicolon after if statement + * Fix soft-fp underflow handling. + * Netfilter: Missing Kbuild entry for netfilter + * SNAP: Fix SNAP protocol header accesses. + * NET: Fix missing rcu unlock in __sock_create() + * SPARC64: Fix sparc64 task stack traces. + * SPARC64: Fix sparc64 PCI config accesses on sun4u + * TCP: Do not autobind ports for TCP sockets + * TCP: Fix TCP rate-halving on bidirectional flows. + * TCP: Fix TCP handling of SACK in bidirectional flows. + * PPP: Fix PPP buffer sizing. + * PCI: lets kill the 'PCI hidden behind bridge' message + * PCI: disable MSI on RS690 + * PCI: disable MSI on RD580 + * PCI: disable MSI on RX790 + * USB: allow retry on descriptor fetch errors + * USB: fix DoS in pwc USB video driver + * usb: add PRODUCT, TYPE to usb-interface events + * Linux 2.6.22.6 + * V4L/DVB (6042): b2c2-flexcop: fix Airstar HD5000 tuning regression + * V4L/DVB (5967): ivtv: fix VIDIOC_S_FBUF:new OSD values where never set + * Re-add _GTM and _STM support + + -- Ben Collins Fri, 31 Aug 2007 16:26:56 -0400 + +linux-source-2.6.22 (2.6.22-10.30) gutsy; urgency=low + + * URGENT upload to fix FTBFS with xen-{i386,amd64} configs, + lpia d-i ftbfs, xen ftbfs. + * URGENT fix module-check to actually ignore things + * URGENT ignore ume modules + + [Alek Du] + + * Add Intel Poulsbo chipset Libata support + + [Amit Kucheria] + + * Update configuration files + * Enable stylus on Lenovo X60/X61 thinkpads + + [Ben Collins] + + * ubuntu: Disable snd-hda-intel, in favor of lum updated version + + [Kyle McMartin] + + * apparmor 10.3 hooks + * add lpia d-i udeb generation + * fix bits of rt/diff for -rt8 + * fix rt/diff for 2.6.22.3 changes + * fix up rt/diff for stable 2.6.22.4 + + [LaMont Jones] + + * Update configuration files + + [Phillip Lougher] + + * WriteSupportForNTFS: make fuse module available to d-i + + [Tim Gardner] + + * Gutsy Tribe 3 CD don't load on Dell Inspiron 1501 + - LP: #121111 + * Update configuration files + * Update configuration files + * Update configuration files + + [Upstream Kernel Changes] + + * [SPARC64]: Fix handling of multiple vdc-port nodes. + * [SPARC64]: Tweak assertions in sun4v_build_virq(). + * [SPARC64]: Fix log message type in vio_create_one(). + * [SPARC64]: Fix two year old bug in early bootup asm. + * [SPARC64]: Improve VIO device naming further. + * [SPARC64]: Handle multiple domain-services-port nodes properly. + * [SPARC64]: Add proper multicast support to VNET driver. + * [SPARC64]: Do not flood log with failed DS messages. + * [SPARC64]: Use KERN_ERR in IRQ manipulation error printks. + * [SPARC64]: Fix virq decomposition. + * [SPARC]: Fix serial console device detection. + * [SPARC64]: fix section mismatch warning in pci_sunv4 + * [SPARC64]: fix section mismatch warning in mdesc.c + * [SPARC64] viohs: extern on function definition + * [SPARC64]: Fix sun4u PCI config space accesses on sun4u. + * [SPARC64]: Fix show_stack() when stack argument is NULL. + * [SUNLANCE]: Fix sparc32 crashes by using of_*() interfaces. + * [SPARC]: Centralize find_in_proplist() instead of duplicating N times. + * [SPARC64]: Fix hard-coding of cpu type output in /proc/cpuinfo on + sun4v. + * [SPARC64]: Do not assume sun4v chips have load-twin/store-init support. + * [SPARC64]: Fix memory leak when cpu hotplugging. + * USB: cdc-acm: fix sysfs attribute registration bug + * TCP FRTO retransmit bug fix + * Fix TC deadlock. + * Fix IPCOMP crashes. + * Fix console write locking in sparc drivers. + * Add a PCI ID for santa rosa's PATA controller. + * Missing header include in ipt_iprange.h + * SCTP scope_id handling fix + * Fix rfkill IRQ flags. + * gen estimator timer unload race + * gen estimator deadlock fix + * Fix error queue socket lookup in ipv6 + * Fix ipv6 link down handling. + * Netpoll leak + * Sparc64 bootup assembler bug + * Fix ipv6 tunnel endianness bug. + * Fix sparc32 memset() + * Fix sparc32 udelay() rounding errors. + * Fix TCP IPV6 MD5 bug. + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * USB: fix warning caused by autosuspend counter going negative + * usb-serial: Fix edgeport regression on non-EPiC devices + * Fix reported task file values in sense data + * aacraid: fix security hole + * firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters) + * make timerfd return a u64 and fix the __put_user + * V4L: Add check for valid control ID to v4l2_ctrl_next + * V4L: ivtv: fix broken VBI output support + * V4L: ivtv: fix DMA timeout when capturing VBI + another stream + * V4L: ivtv: Add locking to ensure stream setup is atomic + * V4L: wm8775/wm8739: Fix memory leak when unloading module + * Input: lifebook - fix an oops on Panasonic CF-18 + * splice: fix double page unlock + * drm/i915: Fix i965 secured batchbuffer usage (CVE-2007-3851) + * Fix leak on /proc/lockdep_stats + * CPU online file permission + * Fix user struct leakage with locked IPC shem segment + * md: handle writes to broken raid10 arrays gracefully + * md: raid10: fix use-after-free of bio + * pcmcia: give socket time to power down + * Fix leaks on /proc/{*/sched, sched_debug, timer_list, timer_stats} + * futex: pass nr_wake2 to futex_wake_op + * "ext4_ext_put_in_cache" uses __u32 to receive physical block number + * Include serial_reg.h with userspace headers + * dm io: fix panic on large request + * i386: HPET, check if the counter works + * fw-ohci: fix "scheduling while atomic" + * firewire: fix memory leak of fw_request instances + * softmac: Fix ESSID problem + * eCryptfs: ecryptfs_setattr() bugfix + * nfsd: fix possible read-ahead cache and export table corruption + * readahead: MIN_RA_PAGES/MAX_RA_PAGES macros + * fs: 9p/conv.c error path fix + * forcedeth bug fix: cicada phy + * forcedeth bug fix: vitesse phy + * forcedeth bug fix: realtek phy + * acpi-cpufreq: Proper ReadModifyWrite of PERF_CTL MSR + * jbd commit: fix transaction dropping + * jbd2 commit: fix transaction dropping + * hugetlb: fix race in alloc_fresh_huge_page() + * do not limit locked memory when RLIMIT_MEMLOCK is RLIM_INFINITY + * uml: limit request size on COWed devices + * sony-laptop: fix bug in event handling + * destroy_workqueue() can livelock + * drivers/video/macmodes.c:mac_find_mode() mustn't be __devinit + * cfq-iosched: fix async queue behaviour + * libata: add FUJITSU MHV2080BH to NCQ blacklist + * ieee1394: revert "sbp2: enforce 32bit DMA mapping" + * nfsd: fix possible oops on re-insertion of rpcsec_gss modules + * dm raid1: fix status + * dm io: fix another panic on large request + * dm snapshot: permit invalid activation + * dm: disable barriers + * cr_backlight_probe() allocates too little storage for struct cr_panel + * ACPI: dock: fix opps after dock driver fails to initialize + * Hangup TTY before releasing rfcomm_dev + * Keep rfcomm_dev on the list until it is freed + * nf_conntrack: don't track locally generated special ICMP error + * IPV6: /proc/net/anycast6 unbalanced inet6_dev refcnt + * sysfs: release mutex when kmalloc() failed in sysfs_open_file(). + * Netfilter: Fix logging regression + * USB: fix for ftdi_sio quirk handling + * sx: switch subven and subid values + * UML: exports for hostfs + * Linux 2.6.22.2 + * fix oops in __audit_signal_info() + * random: fix bound check ordering (CVE-2007-3105) + * softmac: Fix deadlock of wx_set_essid with assoc work + * ata_piix: update map 10b for ich8m + * PPC: Revert "[POWERPC] Don't complain if size-cells == 0 in + prom_parse()" + * PPC: Revert "[POWERPC] Add 'mdio' to bus scan id list for platforms + with QE UEC" + * powerpc: Fix size check for hugetlbfs + * direct-io: fix error-path crashes + * stifb: detect cards in double buffer mode more reliably + * pata_atiixp: add SB700 PCI ID + * CPUFREQ: ondemand: fix tickless accounting and software coordination + bug + * CPUFREQ: ondemand: add a check to avoid negative load calculation + * Linux 2.6.22.3 + * intel_agp: really fix 945/965GME + * Reset current->pdeath_signal on SUID binary execution (CVE-2007-3848) + * MSS(mmc/sd/sdio) driver patch + + -- Kyle McMartin Thu, 16 Aug 2007 12:17:27 -0400 + +linux-source-2.6.22 (2.6.22-9.25) gutsy; urgency=low + + [Kyle McMartin] + + * ubuntu: Fix FTBFS -- forgot to bump debian/abi + + -- Kyle McMartin Thu, 02 Aug 2007 22:13:28 +0000 + +linux-source-2.6.22 (2.6.22-9.24) gutsy; urgency=low + + [Colin Watson] + + * provide Provides for fs-*-modules udebs + + [Matthias Klose] + + * test $dilist before using it + + [Lamont Jones] + + * hppa: Update abi files + + -- Kyle McMartin Thu, 02 Aug 2007 18:26:34 +0000 + +linux-source-2.6.22 (2.6.22-9.23) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Add missing newline to module-check script + * ubuntu: Add lpia to linux-libc-dev. Should finally build now. + + -- Ben Collins Thu, 02 Aug 2007 13:10:23 -0400 + +linux-source-2.6.22 (2.6.22-9.22) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Use DEB_HOST_ARCH, not DEB_HOST_ARCH_CPU + + -- Ben Collins Thu, 02 Aug 2007 08:44:09 -0400 + +linux-source-2.6.22 (2.6.22-9.21) gutsy; urgency=low + + [Ben Collins] + + * lpia: Add build stuff for lpia architecture + + [LaMont Jones] + + * abi files for hppa + * UBUNTU-HPPA: configs that seem to work + * hppa: abi files for 9.20 + + -- Ben Collins Wed, 01 Aug 2007 11:12:59 -0400 + +linux-source-2.6.22 (2.6.22-9.20) gutsy; urgency=low + + [Ben Collins] + + * tulip: Fix for Uli5261 chipsets. + * tulip: Define ULI PCI ID's + * tulip: Let dmfe handle davicom on non-sparc + * input: Allow root to inject unknown scan codes. + * irda: Default to dongle type 9 on IBM hardware + * input/mouse/alps: Do not call psmouse_reset() for alps + * pcmcia: Do not insert pcmcia cards on resume + * ide-cd: Disable verbose errors. + * block: Make CDROMEJECT more robust + * pm: Config option to disable handling of console during suspend/resume. + * version: Implement version_signature proc file. + * update toshiba_acpi to 0.19a-dev + * xpad: Update to latest version from xbox-linux. + * ubuntu: Enable setting of CONFIG_VERSION_SIGNATURE at build time + * toshiba_acpi: Don't use init_MUTEX_LOCKED + + [Chuck Short] + + * [USB]: add ASUS LCM to the blacklist + * [NET]: Add mcp73 to forcedeth. + * [USB]: Added support for Sanwa PC5000 multimeter usb cable (KB-USB2). + * [ATA] Add support for Sb700 AHCI nor-raid5 and raid5 + + [Fabio M. Di Nitto] + + * drivers/char/vt.c: make promcon driver init a boot option. + + [Kyle McMartin] + + * Disable MMCONFIG by default + + [Phillip Lougher] + + * fix NFS mounting regression from Edgy->Feisty + * r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Tim Gardner] + + * Catch nonsense keycodes and silently ignore + * Cause SoftMac to emit an association event when setting ESSID. + + -- Ben Collins Mon, 30 Jul 2007 12:01:43 -0400 + +linux-source-2.6.22 (2.6.22-9.19) gutsy; urgency=low + + [Amit Kucheria] + + * Fix for FTBFS bug 123178 + * Fix for FTBFS bug 123178 + * Add devices to USB quirks to prevent USB autosuspend + * More devices added to USB quirks + - LP: #85488 + * Support for ENE CB-712/4 SD card reader + * Reorder quirk list based on Vendor/Product ID + + [Ben Collins] + + * ubuntu: Enable HOTPLUG_CPU in sparc64-smp config. + * ubuntu: Add xen to amd64 custom builds + * ubuntu: Update real-time kernel to -rt4 + * rt: Patch from Alessio Igor Bogani for RT-8 + + [Chuck Short] + + * IDE: add MHV2080BH to NCQ blacklist + * XEN: update to 2.6.22 final and amd64 support. + * NET: Add more pci-ids to zd1211rw + * IDE: add new PCI ID + * USB: fix oops in ftdi_sio + + [Eric Piel] + + * ACPI: Allow custom DSDT tables to be loaded from initramfs + + [Ryan Lortie] + + * Macbook calibration loop fix + - LP: #54621 + + [Upstream Kernel Changes] + + * NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr + dereference (CVE-2007-2876) + * Linux 2.6.22.1 + * [SPARC64]: Use KERN_ERR in sun4v IRQ printk()'s. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + * [SPARC64]: Assorted LDC bug cures. + * [SPARC64]: Add domain-services nodes to VIO device tree. + * [SPARC64]: Export powerd facilities for external entities. + * [SPARC64]: Initial domain-services driver. + * [SPARC64]: Use more mearningful names for IRQ registry. + * [SPARC64]: Abstract out mdesc accesses for better MD update handling. + * [SPARC64]: Fix MD property lifetime bugs. + * [SPARC64]: Fix setting of variables in LDOM guest. + * [SPARC64]: Initial LDOM cpu hotplug support. + * [SPARC64]: Unconditionally register vio_bus_type. + * [SPARC64]: Fix build regressions added by dr-cpu changes. + * [SPARC64]: mdesc.c needs linux/mm.h + * [SPARC64]: SMP build fixes. + * [SPARC64]: More sensible udelay implementation. + * [SPARC64]: Process dr-cpu events in a kthread instead of workqueue. + * [SPARC64]: Add ->set_affinity IRQ handlers. + * [SPARC64]: Fix leak when DR added cpu does not bootup. + * [SPARC64]: Clear cpu_{core,sibling}_map[] in + smp_fill_in_sib_core_maps() + * [SPARC64]: Give more accurate errors in dr_cpu_configure(). + * [SERIAL]: Fix console write locking in sparc drivers. + * [TIMER]: Fix clockevent notifications on 64-bit. + * [SPARC64]: dr-cpu unconfigure support. + * [SPARC64]: Fix UP build. + * [SPARC64]: SMP build fix. + * [SPARC64]: Fix race between MD update and dr-cpu add. + * [SERIAL] SUNHV: Fix jerky console on LDOM guests. + * [SPARC64]: Kill explicit %gl register reference. + * [SPARC64]: Add basic infrastructure for MD add/remove notification. + * [SPARC64]: Simplify VDC device probing. + * [SPARC64]: Simplify VNET probing. + * [SPARC64]: Massively simplify VIO device layer and support hot + add/remove. + * [SPARC64]: Handle LDC resets properly in domain-services driver. + * [SPARC64]: Handle reset events in vio_link_state_change(). + * [SPARC64]: Fix reset handling in VNET driver. + * [SPARC64]: Set vio->desc_buf to NULL after freeing. + * [SPARC64]: Fix MODULE_DEVICE_TABLE() specification in VDC and VNET. + * [SPARC64]: Fix device type matching in VIO's devspec_show(). + * Add empty + * Add dummy isa_(bus|virt)_to_(virt|bus) inlines + * Clean up sti_flush + * Do not allow STI_CONSOLE to be modular + * Use compat_sys_getdents + + -- Ben Collins Sat, 28 Jul 2007 12:30:53 -0400 + +linux-source-2.6.22 (2.6.22-8.18) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: *sigh* update xen config to fix FTBFS + + -- Ben Collins Thu, 12 Jul 2007 14:23:20 +0100 + +linux-source-2.6.22 (2.6.22-8.17) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Actually enable the -xen build. + + -- Ben Collins Thu, 12 Jul 2007 09:51:01 +0100 + +linux-source-2.6.22 (2.6.22-8.16) gutsy; urgency=low + + * Removed CONFIG_BLINK from all configs and added to modules.ignore + * This fixes a build failure for 8.15 + + [Alexey Starikovskiy] + + * Fix ACPI battery detection on Asus + + [Amit Kucheria] + + * Export symbols required to build GFS1 in LUM + * Update configuration files + * 2.6.22-7.14 ABI + * Remove old ABI + * Update d-i modules to support Sparc LDOM + * Introducing the UME kernel flavour + + [Jacob Pan] + + * Poulsbo SMBus Controller + * Intel Poulsbo SCH IDE Controller + * Intel Poulsbo HD audio controller + + [Phillip Lougher] + + * xen: Update custom binary flavour (Xen 3.1 for 2.6.22-rc5) + * xen: Update xen/config.i386 to enable PAE + + [Upstream Kernel Changes] + + * [SCSI] fusion: fix for BZ 8426 - massive slowdown on SCSI CD/DVD drive + * [XFS] Update the MAINTAINERS file entry for XFS. + * IB/mlx4: Fix handling of wq->tail for send completions + * IB/mlx4: Fix warning in rounding up queue sizes + * [SCSI] ESP: Don't forget to clear ESP_FLAG_RESETTING. + * firewire: fix hang after card ejection + * ieee1394: fix to ether1394_tx in ether1394.c + * [ARM] Add support for pause_on_oops and display preempt/smp options + * sh: Fix restartable syscall arg5 clobbering. + * ACPI: gracefully print null trip-point device + * ACPICA: fix error path in new external package objects as method + arguments + * sh: oops_enter()/oops_exit() in die(). + * [ARM] Update show_regs/oops register format + * IB/mlx4: Handle new FW requirement for send request prefetching + * IB/mlx4: Get rid of max_inline_data calculation + * IB/mlx4: Handle buffer wraparound in __mlx4_ib_cq_clean() + * IB/mlx4: Handle FW command interface rev 3 + * Fix signalfd interaction with thread-private signals + * sched: fix SysRq-N (normalize RT tasks) + * Fix possible runqueue lock starvation in wait_task_inactive() + * sh: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * sh64: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * [POWERPC] Fix snd-powermac refcounting bugs + * [XFS] s/memclear_highpage_flush/zero_user_page/ + * [XFS] Update the MAINTAINERS file entry for XFS - change git repo name. + * [XFRM]: Fix MTU calculation for non-ESP SAs + * [IPVS]: Fix state variable on failure to start ipvs threads + * [AF_RXRPC]: Return the number of bytes buffered in rxrpc_send_data() + * [S390] Missing blank when appending cio_ignore kernel parameter + * [S390] Fix zfcpdump header + * [S390] Fix yet another two section mismatches. + * [S390] Print list of modules on die(). + * [S390] Add oops_enter()/oops_exit() calls to die(). + * [S390] Move psw_set_key. + * [POWERPC] rheap - eliminates internal fragments caused by alignment + * [POWERPC] PowerPC: Prevent data exception in kernel space (32-bit) + * [POWERPC] Fix powermac late initcall to only run on powermac + * [MIPS] Don't drag a platform specific header into generic arch code. + * x86_64: Fix readahead/sync_file_range/fadvise64 compat calls + * x86_64: Fix eventd/timerfd syscalls + * x86: Disable DAC on VIA bridges + * x86_64: Quieten Atari keyboard warnings in Kconfig + * x86: Only make Macintosh drivers default on Macs + * x86: Disable KPROBES with DEBUG_RODATA for now + * x86: change_page_attr bandaids + * x86_64: fix link warning between for .text and .init.text + * Fix up CREDIT entry ordering + * firewire: Only set client->iso_context if allocation was successful. + * spidernet: null out skb pointer after its been used. + * spidernet: Cure RX ram full bug + * spidernet: Don't terminate the RX ring + * spidernet: silence the ramfull messages + * spidernet: turn off descriptor chain end interrupt. + * spidernet: checksum and ethtool + * bonding: Fix use after free in unregister path + * bonding: Fix 802.3ad no carrier on "no partner found" instance + * s390: print correct level for HiperSockets devices + * s390: qeth driver does not recover + * s390: avoid inconsistent lock state in qeth + * s390: qeth: wrong packet length in qdio header + * s390: Use ccw_device_get_id() in qeth/claw drivers + * s390: don't call iucv_path_connect from tasklet context + * s390: netiucv spinlock initializer cleanup + * s390: netiucv inlining cleanup + * forcedeth: use unicast receive mode for WoL + * natsemi irq flags + * cxgb3 - fix skb->dev dereference + * cxgb3 - fix netpoll hanlder + * cxgb3 - Fix direct XAUI support + * cxgb3 - Stop mac RX when changing MTU + * cxgb3 - MAC watchdog update + * PATA: Add the MCP73/77 support to PATA driver + * pata_it821x: (partially) fix DMA in RAID mode + * libata: more NONCQ devices + * kerneldoc fix in libata + * ahci: fix PORTS_IMPL override + * fix module_param mistake in it821x + * Blackfin arch: update ANOMALY handling + * Blackfin arch: update printk to use KERN_EMERG and reformat crash + output + * Blackfin arch: add missing braces around array bfin serial init + * Blackfin arch: match kernel startup messaage with new linker script + * Blackfin arch: move cond_syscall() behind __KERNEL__ like all other + architectures + * Blackfin arch: Add definition of dma_mapping_error + * Blackfin arch: add proper const volatile to addr argument to the read + functions + * [AGPGART] intel_agp: don't load if no IGD and AGP port + * IB/umem: Fix possible hang on process exit + * IPoIB/cm: Initialize RX before moving QP to RTR + * IPoIB/cm: Fix interoperability when MTU doesn't match + * IPoIB/cm: Remove dead definition of struct ipoib_cm_id + * IB/mlx4: Correct max_srq_wr returned from mlx4_ib_query_device() + * [PARISC] stop lcd driver from stripping initial whitespace + * [PARISC] Handle wrapping in expand_upwards() + * [PARISC] Fix unwinder on 64-bit kernels + * [PARISC] unwinder improvements + * page_mapping must avoid slub pages + * posix-timers: Prevent softirq starvation by small intervals and SIG_IGN + * Allow DEBUG_RODATA and KPROBES to co-exist + * [NETFILTER]: nf_conntrack_sip: add missing message types containing RTP + info + * [NETFILTER]: nfctnetlink: Don't allow to change helper + * [IPV6] NDISC: Fix thinko to control Router Preference support. + * [IPV4]: include sysctl.h from inetdevice.h + * i386: Make CMPXCHG64 only dependent on PAE + * x86_64: Fix only make Macintosh drivers default on Macs + * x86_64: Ignore compat mode SYSCALL when IA32_EMULATION is not defined + * [AVR32] Fix bug in invalidate_dcache_region() + * [AVR32] NGW100, Remove relics of the old USART mapping scheme + * [AVR32] Initialize dma_mask and dma_coherent_mask + * [AVR32] Update defconfigs + * ACPI: fix 2.6.20 SMP boot regression + * [SKBUFF]: Fix incorrect config #ifdef around skb_copy_secmark + * [TIPC]: Fix infinite loop in netlink handler + * [PPP]: Revert 606f585e363527da9feaed79465132c0c661fd9e + * [PPP]: Fix osize too small errors when decoding mppe. + * [TCP] tcp_read_sock: Allow recv_actor() return return negative error + value. + * [NET]: Re-enable irqs before pushing pending DMA requests + * [NET]: Make skb_seq_read unmap the last fragment + * hwmon/coretemp: fix a broken error path + * fix refcounting of nsproxy object when unshared + * console UTF-8 fixes (fix) + * SM501: suspend support + * SM501: initialise SDRAM clock before bus clocks + * SM501: Fix sm501_init_reg() mask/set order + * SM501: Clock updates and checks + * SM501: Add Documentation/SM501.txt + * SM501: Check SM501 ID register on initialisation + * SLUB: fix behavior if the text output of list_locations overflows + PAGE_SIZE + * sched: fix next_interval determination in idle_balance() + * update checkpatch.pl to version 0.05 + * alpha: fix alignment problem in csum_ipv6_magic() + * Char: stallion, fix oops during init with ISA cards + * uml: use generic BUG + * uml: add asm/paravirt.h + * "volatile considered harmful" + * document nlink function + * slab allocators: MAX_ORDER one off fix + * update checkpatch.pl to version 0.06 + * x86_64: fix misplaced `continue' in mce.c + * ext2: disallow setting xip on remount + * audit: fix oops removing watch if audit disabled + * ext3: lost brelse in ext3_read_inode() + * ext4: lost brelse in ext4_read_inode() + * ACPI: preserve the ebx value in acpi_copy_wakeup_routine + * FUTEX: Restore the dropped ERSCH fix + * Linus 2.6.22-rc6 + * [ARM] 4452/1: Force the literal pool dump before reloc_end + * [ARM] 4449/1: more entries in arch/arm/boot/.gitignore + * fix nmi_watchdog=2 bootup hang + * [POWERPC] Update g5_defconfig + * [POWERPC] Update defconfigs + * [POWERPC] Fix VDSO gettimeofday() when called with NULL struct timeval + * [POWERPC] Fix subtle FP state corruption bug in signal return on SMP + * USB: g_file_storage: call allow_signal() + * USB: ti serial driver sleeps with spinlock held + * USB: memory leak in iowarrior.c + * USB: usblcd doesn't limit memory consumption during write + * USB: fix race leading to use after free in io_edgeport + * USB: add new device id to option driver + * USB: ftdio_sio: New IPlus device ID + * [MIPS] __ucmpdi2 arguments are unsigned long long. + * [MIPS] add io_map_base to pci_controller on Cobalt + * [MIPS] remove "support for" from system type entry + * [MIPS] Alchemy: Fix wrong cast + * [MIPS] Fix pb1500 reg B access + * [MIPS] AP/SP requires shadow registers, auto enable support. + * [MIPS] 20K: Handle WAIT related bugs according to errata information + * [MIPS] use compat_siginfo in rt_sigframe_n32 + * [MIPS] Remove a duplicated local variable in test_and_clear_bit() + * [MIPS] EMMA2RH: Disable GEN_RTC, it can't possibly work. + * [MIPS] SMTC and non-SMTC kernel and modules are incompatible + * [MIPS] Count timer interrupts correctly. + * x86_64: set the irq_chip name for lapic + * x86_64 irq: use mask/unmask and proper locking in fixup_irqs() + * [SPARC64]: Add irqs to mdesc_node. + * [SPARC64]: Fix VIRQ enabling. + * [SPARC64]: Need to set state to IDLE during sun4v IRQ enable. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [GFS2] Fix gfs2_block_truncate_page err return + * [DLM] Telnet to port 21064 can stop all lockspaces + * [GFS2] inode size inconsistency + * [GFS2] remounting w/o acl option leaves acls enabled + * [GFS2] System won't suspend with GFS2 file system mounted + * [GFS2] git-gfs2-nmw-build-fix + * [GFS2] Obtaining no_formal_ino from directory entry + * [GFS2] Remove i_mode passing from NFS File Handle + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + + -- Amit Kucheria Mon, 09 Jul 2007 12:55:56 +0300 + +linux-source-2.6.22 (2.6.22-7.14) gutsy; urgency=low + + [Ben Collins] + + * build/vars: Provide ivtv-modules + * Bump ABI + * ubuntu/config: Enable Intermediate Functional Block device + * coredump: Fix typo in patch merge + * ubuntu/scripts: Make sure to symlink *.lds for ia64 builds + * ubuntu/config: Enable NO_HZ for server and sparc64 targets. + * ubuntu/config: Remove bigiron target, see if anyone complains + * ubuntu: Ok, really remove bigiron + * ubuntu/control-scripts: Fo sho, remove the debconf stuff from controls + scripts + * AppArmor: Enable exports and changes for AppArmor usage + * ubuntu: Add feisty changelog for historical purposes. + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * [MTD] [MAPS] don't force uclinux mtd map to be root dev + * [MTD] generalise the handling of MTD-specific superblocks + * [SCSI] zfcp: avoid clutter in erp_dbf + * [SCSI] zfcp: IO stall after deleting and path checker changes after + reenabling zfcp devices + * [SCSI] ipr: Proper return codes for eh_dev_reset for SATA devices + * [SCSI] stex: fix id mapping issue + * [SCSI] stex: extend hard reset wait time + * [SCSI] stex: fix reset recovery for console device + * [SCSI] stex: minor cleanup and version update + * [SCSI] MegaRAID: Update MAINTAINERS email-id + * [SCSI] tgt: fix a rdma indirect transfer error bug + * [SCSI] NCR53C9x: correct spelling mistake in deprecation notice + * [SCSI] aacraid: Correct sa platform support. (Was: [Bug 8469] Bad EIP + value on pentium3 SMP kernel-2.6.21.1) + * [SCSI] aacraid: fix panic on short Inquiry + * [WATCHDOG] ks8695_wdt.c - new KS8695 watchdog driver + * [JFFS2] Fix BUG() caused by failing to discard xattrs on deleted files. + * [JFFS2] Fix potential memory leak of dead xattrs on unmount. + * [SCSI] sd: fix refcounting regression in suspend/resume routines + * [SCSI] aacraid: apply commit config for reset_devices flag + * [SCSI] aic7xxx: fix aicasm build failure with gcc-3.4.6 + * [SCSI] aic94xx: asd_clear_nexus should fail if the cleared task does + not complete + * [SCSI] fusion: Fix |/|| confusion + * parisc: make command_line[] static + * parisc: sync compat getdents + * [PARISC] Move #undef to end of syscall table + * [PARISC] Wire up kexec_load syscall + * parisc: convert /proc/gsc/pcxl_dma to seq_file + * [PARISC] Let PA-8900 processors boot + * [PARISC] Disable LWS debugging + * [PARISC] spelling fixes: arch/parisc/ + * sh: section mismatch fixes for system timer. + * [PARISC] ROUND_UP macro cleanup in arch/parisc + * [PARISC] ROUNDUP macro cleanup in drivers/parisc + * [PPC] Fix COMMON symbol warnings + * [PPC] Remove duplicate export of __div64_32. + * [POWERPC] 52xx: unbreak lite5200 dts (_pic vs. -pic) + * [POWERPC] QE: fix Kconfig 'select' warning with UCC_FAST + * [POWERPC] Fix Section mismatch warnings + * [POWERPC] Fix modpost warning + * [PPC] Fix modpost warning + * [CIFS] Fix oops on failed cifs mount (in kthread_stop) + * [POWERPC] Fix Kconfig warning + * [CIFS] typo in previous patch + * [SCSI] megaraid_sas: intercept cmd timeout and throttle io + * [WATCHDOG] clean-up watchdog documentation + * drm: Spinlock initializer cleanup + * drm/radeon: add more IGP chipset pci ids + * drm: make sure the drawable code doesn't call malloc(0). + * [PARISC] kobject is embedded in subsys, not kset + * [PARISC] Build fixes for power.c + * [ARM] 4401/1: S3C2443: Add definitions for port GPIOJ + * [ARM] 4402/1: S3C2443: Add physical address of HSMMC controller + * [ARM] 4403/1: Make the PXA-I2C driver work with lockdep validator + * [ARM] 4404/1: Trivial IXP42x Kconfig cleanup + * [ARM] 4405/1: NSLU2, DSM-G600 frequency fixup code + * [ARM] 4406/1: Trivial NSLU2 / NAS-100D header & setup code cleanup + * [ARM] remove unused header file: arch/arm/mach-s3c2410/bast.h + * [PARISC] fix lasi_82596 build + * [PARISC] fix section mismatch in parport_gsc + * [PARISC] fix section mismatch in parisc STI video drivers + * [PARISC] fix section mismatch in ccio-dma + * [PARISC] fix section mismatches in arch/parisc/kernel + * [PARISC] fix section mismatch in parisc eisa driver + * [PARISC] fix section mismatch in superio serial drivers + * [PARISC] Wire up utimensat/signalfd/timerfd/eventfd syscalls + * hwmon/ds1621: Fix swapped temperature limits + * hwmon/coretemp: Add more safety checks + * hwmon/w83627hf: Be quiet when no chip is found + * hwmon-vid: Don't spam the logs when VRM version is missing + * hwmon/applesmc: Simplify dependencies + * hwmon/applesmc: Handle name file creation error and deletion + * ieee1394: sbp2: include workqueue.h + * ieee1394: eth1394: remove bogus netif_wake_queue + * ieee1394: eth1394: handle tlabel exhaustion + * ieee1394: eth1394: bring back a parent device + * ieee1394: raw1394: Fix async send + * firewire: Add missing byteswapping for receive DMA programs. + * firewire: prefix modules with firewire- instead of fw- + * firewire: fix return code + * [libata] Add drive to NCQ blacklist + * [ARM] enable arbitary speed tty ioctls and split input/output speed + * Input: db9 - do not ignore dev2 module parameter + * Input: logips2pp - fix typo in Kconfig + * [XFS] Write at EOF may not update filesize correctly. + * [SCSI] pluto: Use wait_for_completion_timeout. + * [SPARC64]: Kill unused DIE_PAGE_FAULT enum value. + * [SPARC64]: Don't be picky about virtual-dma values on sun4v. + * [SPARC32]: Removes mismatch section warnigs in sparc time.c file + * [SERIAL] sunzilog: section mismatch fix + * [SPARC64]: PCI device scan is way too verbose by default. + * [SCSI] jazz_esp: Converted to use esp_core. + * [SCSI] ESP: Kill SCSI_ESP_CORE and link directly just like jazz_esp + * [SPARC64]: Fix typo in sun4v_hvapi_register error handling. + * [SPARC64]: Report proper system soft state to the hypervisor. + * [SPARC64]: Negotiate hypervisor API for PCI services. + * [SPARC64]: Use machine description and OBP properly for cpu probing. + * [SPARC64]: Eliminate NR_CPUS limitations. + * [SPARC64]: arch/sparc64/time.c doesn't compile on Ultra 1 (no PCI) + * [SPARC]: Linux always started with 9600 8N1 + * [SPARC64]: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler. + * [SPARC]: Emulate cmpxchg like parisc + * [SPARC]: Mark as emulating cmpxchg, add appropriate depends for DRM. + * [SPARC64]: Fix two bugs wrt. kernel 4MB TSB. + * [SPARC64]: Fill holes in hypervisor APIs and fix KTSB registry. + * mac80211: fail back to use associate from reassociate + * mac80211: fix memory leak when defrag fragments + * mac80211: always set carrier status on open + * mac80211: avoid null ptr deref in ieee80211_ibss_add_sta + * prism54: fix monitor mode oops + * ieee80211: fix incomplete error message + * softmac: alloc_ieee80211() NULL check + * hostap: Allocate enough tailroom for TKIP + * sparc64: fix alignment bug in linker definition script + * USB: replace flush_workqueue with cancel_sync_work + * ACPICA: allow Load(OEMx) tables + * ACPI: thermal: Replace pointer with name in trip_points + * ACPI: extend "acpi_osi=" boot option + * IB/mthca: Fix handling of send CQE with error for QPs connected to SRQ + * IPoIB/cm: Fix performance regression on Mellanox + * IB/cm: Fix stale connection detection + * IB/mlx4: Fix last allocated object tracking in bitmap allocator + * NOHZ: prevent multiplication overflow - stop timer for huge timeouts + * random: fix error in entropy extraction + * random: fix seeding with zero entropy + * ACPI: Make _OSI(Linux) a special case + * ACPI: add __init to acpi_initialize_subsystem() + * [PARISC] fix "ENTRY" macro redefinition + * [PARISC] fix section mismatch in smp.c + * [PARISC] remove remnants of parisc-specific softirq code + * [PARISC] fix trivial spelling nit in asm/linkage.h + * [PARISC] fix null ptr deref in unwind.c + * [PARISC] fix "reduce size of task_struct on 64-bit machines" fallout + * [PARISC] be more defensive in process.c::get_wchan + * [ARM] use __used attribute + * [ARM] Fix stacktrace FP range checking + * [ARM] oprofile: avoid lockdep warnings on mpcore oprofile init + * [ARM] 4411/1: KS8695: Another serial driver fix + * [ARM] 4412/1: S3C2412: reset errata fix + * [ARM] 4414/1: S3C2443: sparse fix for clock.c + * [ARM] 4415/1: AML5900: fix sparse warnings from map_io + * [ARM] 4416/1: NWFPE: fix undeclared symbols + * [ARM] 4410/1: Remove extern declarations in coyote/ixdpg425-pci.c + * [ARM] 4394/1: ARMv7: Add the TLB range operations + * [ARM] 4417/1: Serial: Fix AMBA drivers locking + * sky2: dont set bogus bit in PHY register + * sky2: checksum offload plus vlan bug + * sky2: program proper register for fiber PHY + * defxx: Fix the handling of ioremap() failures + * e1000: restore netif_poll_enable call but make sure IRQs are off + * sky2: enable IRQ on duplex renegotiation + * ehea: Fixed multi queue RX bug + * [SCSI] fix CONFIG_SCSI_WAIT_SCAN=m + * [SCSI] qla2xxx: fix timeout in qla2x00_down_timeout + * [ARM] Fix some section mismatch warnings + * alpha: cleanup in bitops.h + * alpha: support new syscalls + * fix possible null ptr deref in kallsyms_lookup + * NFS: Fix a refcount leakage in O_DIRECT + * a bug in ramfs_nommu_resize function, passing old size to vmtruncate + * sh: Fix pcrel too far for in_nmi label. + * sh: Trivial fix for dma-api compile failure. + * sh: Fix vsyscall build failure. + * sh: trivial build cleanups. + * sh: support older gcc's + * [ALSA] HDA: Add support for Gateway NX860 + * [ALSA] HDA: Add more systems to Sigmatel codec + * [ALSA] HDA: Fix headphone mute issue on non-eapd Conexant systems + * [ALSA] hda-codec - Add support for ASUS A8J modem + * [ALSA] ali5451 - Fix possible NULL dereference + * [ALSA] hda-intel: fix ASUS M2V detection + * [ALSA] Fix ASoC s3c24xx-pcm spinlock bug + * [ALSA] hda-codec - Add quirk for MSI S420 + * [ALSA] hda-codec - Add quirk for Supermicro PDSBA to alc883_cfg_tbl[] + * [ALSA] hda-codec - Add support for MSI K9N Ultra + * [ALSA] hda-codec - Fix pin configs for Gateway MX6453 + * [ALSA] hda-codec - Fix input with STAC92xx + * [ALSA] hda-codec - Fix STAC922x capture boost level + * [CRYPTO] cryptd: Fix problem with cryptd and the freezer + * [CASSINI]: Fix printk message typo. + * [XFRM]: Allow XFRM_ACQ_EXPIRES to be tunable via sysctl. + * [XFRM]: xfrm_larval_drop sysctl should be __read_mostly. + * [IPSEC]: Fix IPv6 AH calculation in outbound + * [IPV6] ROUTE: No longer handle ::/0 specially. + * [NET]: parse ip:port strings correctly in in4_pton + * [IPSEC]: Fix panic when using inter address familiy IPsec on loopback. + * [IPV4]: Kill references to bogus non-existent CONFIG_IP_NOSIOCRT + * [AF_PACKET]: Kill bogus CONFIG_PACKET_MULTICAST + * [IPV6]: Fix build warning. + * [AF_PACKET]: Kill CONFIG_PACKET_SOCKET. + * [SOCK]: Shrink struct sock by 8 bytes on 64-bit. + * [TCP]: Consolidate checking for tcp orphan count being too big. + * [NET] napi: Call __netif_rx_complete in netif_rx_complete + * [IPV6] ADDRCONF: Fix conflicts in DEVCONF_xxx constant. + * [TCP] tcp_probe: a trivial fix for mismatched number of printl + arguments. + * [TCP] tcp_probe: use GCC printf attribute + * [BRIDGE]: Reduce frequency of forwarding cleanup timer in bridge. + * [BRIDGE]: Round off STP perodic timers. + * [IPSEC]: Add xfrm_sysctl.txt. + * [SPARC64]: Add missing NCS and SVC hypervisor interfaces. + * [SPARC32]: Build fix. + * [SPARC]: Missing #include in drivers/sbus/char/flash.c + * [ALSA] version 1.0.14 + * neofb: Fix pseudo_palette array overrun in neofb_setcolreg + * smpboot: fix cachesize comparison in smp_tune_scheduling() + * at91: fix enable/disable_irq_wake symmetry in pcmcia driver + * SLUB: More documentation + * pci-quirks: fix MSI disabling on RS400-200 and RS480 + * ntfs_init_locked_inode(): fix array indexing + * m68k: runtime patching infrastructure + * SLUB: Fix NUMA / SYSFS bootstrap issue + * afs: needs sched.h + * m68k: discontinuous memory support + * [S390] Add exception handler for diagnose 224 + * [S390] dasd_eer: use mutex instead of semaphore + * [S390] arch/s390/kernel/debug.c: use mutex instead of semaphore + * [S390] raw3270: use mutex instead of semaphore + * [S390] Fix section annotations. + * [S390] cio: Use device_schedule_callback() for removing disconnected + devices. + * [S390] cio: deregister ccw device when pgid disband failed + * ACPI: thinkpad-acpi: do not use named sysfs groups + * ieee1394: fix calculation of sysfs attribute "address" + * ieee1394: sbp2: offer SAM-conforming target port ID in sysfs + * firewire: fw-sbp2: implement sysfs ieee1394_id + * firewire: add to MAINTAINERS + * firewire: Implement suspend/resume PCI driver hooks. + * firewire: Change struct fw_cdev_iso_packet to not use bitfields. + * firewire: Install firewire-constants.h and firewire-cdev.h for + userspace. + * EXT4: Fix whitespace + * Remove unnecessary exported symbols. + * ext4: Extent overlap bugfix + * When ext4_ext_insert_extent() fails to insert new blocks + * Define/reserve new ext4 superblock fields + * msi: fix ARM compile + * PCI: disable MSI by default on systems with Serverworks HT1000 chips + * PCI: Fix pci_find_present + * PCI: i386: fixup for Siemens Nixdorf AG FSC Multiprocessor Interrupt + Controllers + * PCI: quirk disable MSI on via vt3351 + * [XTENSA] fix bit operations in bitops.h + * [XTENSA] Spelling fixes in arch/xtensa + * [XTENSA] fix sources using deprecated assembler directive + * [XTENSA] Remove multi-exported symbols from xtensa_ksyms.c + * [XTENSA] Use generic 64-bit division + * [XTENSA] clean-up header files + * [XTENSA] Move common sections into bss sections + * [XTENSA] Remove non-rt signal handling + * Xtensa: use asm-generic/fcntl.h + * [JFFS2] Fix buffer length calculations in jffs2_get_inode_nodes() + * Fix vmi.c compilation + * x86_64: allocate sparsemem memmap above 4G + * Add select PHYLIB to the UCC_GETH Kconfig option + * Fix possible UDF data corruption + * m68k: parenthesis balance + * msi: fix the ordering of msix irqs + * msi: mask the msix vector before we unmap it + * potential parse error in ifdef + * parse errors in ifdefs + * pci_ids: update patch for Intel ICH9M + * x86: fix oprofile double free + * Work around Dell E520 BIOS reboot bug + * fix compat futex code for private futexes + * skeletonfb: fix of xxxfb_setup ifdef + * vt8623fb: arkfb: null pointer dereference fix + * cfag12864bfb: Use sys_ instead of cfb_ framebuffer accessors + * fbdev: Move declaration of fb_class to + * misc/tifm_7xx1: replace deprecated irq flag + * add a trivial patch style checker + * Documentation: How to use GDB to decode OOPSes + * RTC: use fallback IRQ if PNP tables don't provide one + * memory hotplug: fix unnecessary calling of init_currenty_empty_zone() + * tty: fix leakage of -ERESTARTSYS to userland + * ISDN4Linux: fix maturity label + * Fix broken CLIR in isdn driver + * prism54: MAINTAINERS update + * atmel_spi dma address bugfix + * h8300 trival patches + * ALPHA: support graphics on non-zero PCI domains + * ALPHA: correct low-level I/O routines for sable-lynx + * ALPHA: misc fixes + * Better documentation for ERESTARTSYS + * serial_core.h: include + * SPI: Freescale iMX SPI controller driver fixes + * SLUB: fix locking for hotplug callbacks + * pm3fb: switching between X and fb fix + * microcode: fix section mismatch warning + * isdn: fix section mismatch warnings + * acpi: fix section mismatch warning in asus + toshiba + * kvm: fix section mismatch warning in kvm-intel.o + * net/hp100: fix section mismatch warning + * timer statistics: fix race + * timer stats: speedups + * [SCSI] aacraid: fix shutdown handler to also disable interrupts. + * [MTD] Fix error checking after get_mtd_device() in get_sb_mtd functions + * [JFFS2] Fix obsoletion of metadata nodes in jffs2_add_tn_to_tree() + * ACPI: Section mismatch ... acpi_map_pxm_to_node + * ACPICA: Support for external package objects as method arguments + * Pull now into release branch + * Pull osi-now into release branch + * [POWERPC] Update documentation for of_find_node_by_type() + * [POWERPC] Fix ppc32 single-stepping out of syscalls + * [POWERPC] Fix compiler/assembler flags for Ebony platform boot files + * [POWERPC] Fix possible access to free pages + * [POWERPC] ps3/interrupt.c uses get_hard_smp_processor_id + * [POWERPC] pasemi idle uses hard_smp_processor_id + * [POWERPC] Create a zImage for legacy iSeries + * [POWERPC] Don't use HOSTCFLAGS in BOOTCFLAGS + * [POWERPC] Fix compile warning in pseries xics code + * [POWERPC] Fix return from pte_alloc_one() in out-of-memory case + * [POWERPC] Compare irq numbers with NO_IRQ not IRQ_NONE + * [POWERPC] Don't allow PMAC_APM_EMU for 64-bit + * [POWERPC] Fix compile breakage for IBM/AMCC 4xx arch/ppc platforms + * [POWERPC] Fix zImage.coff generation for 32-bit pmac + * [ARM] 4392/2: Do not corrupt the SP register in compressed/head.S + * [ARM] 4418/1: AT91: Number of programmable clocks differs + * [ARM] 4419/1: AT91: SAM9 USB clocks check for suspending + * [ARM] 4422/1: Fix default value handling in gpio_direction_output (PXA) + * [ARM] Solve buggy smp_processor_id() usage + * qla3xxx: device doesnt do hardware checksumming. + * VLAN: kill_vid is only useful for VLAN filtering devices + * sky2: Fix VLAN unregistration + * 8139cp: fix VLAN unregistration + * atl1: eliminate unneeded kill_vid code + * network drivers: eliminate unneeded kill_vid code + * e1000: disable polling before registering netdevice + * smc91x: sh solution engine fixes. + * Update tulip maintainer email address + * NetXen: Removal of extra free_irq call + * myri10ge: report link up/down in standard ethtool way + * NET: add MAINTAINERS entry for ucc_geth driver + * [ARM] 4421/1: AT91: Value of _KEY fields. + * [PARISC] Fix bug when syscall nr is __NR_Linux_syscalls + * [AF_UNIX]: Make socket locking much less confusing. + * [TG3]: Fix link problem on Dell's onboard 5906. + * [AF_UNIX]: Fix datagram connect race causing an OOPS. + * [TCP]: Use default 32768-61000 outgoing port range in all cases. + * [ATM]: Fix warning. + * [NET]: Make net watchdog timers 1 sec jiffy aligned. + * [NET]: Fix comparisons of unsigned < 0. + * [TCP]: Fix GSO ignorance of pkts_acked arg (cong.cntrl modules) + * [NET] gso: Fix GSO feature mask in sk_setup_caps + * [IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP + * [ICMP]: Fix icmp_errors_use_inbound_ifaddr sysctl + * [VIDEO]: XVR500 and XVR2500 require FB=y + * [ATA]: Don't allow to enable this for SPARC64 without PCI. + * sh: Fix in_nmi symbol build error. + * sh: microdev: Fix compile warnings. + * sh: Fix SH4-202 clock fwk set_rate() mismatch. + * sh: voyagergx: Fix build warnings. + * sh: ioremap() through PMB needs asm/mmu.h. + * sh: Fix se73180 platform device registration. + * Input: ucb1x00 - do not access input_dev->private directly + * Input: reduce raciness when input handlers disconnect + * [PARISC] Fix kernel panic in check_ivt + * [SCSI] atari_NCR5380: update_timeout removal + * [SCSI] JAZZ ESP and SUN ESP need SPI_ATTRS + * [CIFS] fix mempool destroy done in wrong order in cifs error path + * SPI dynamic busid generation bugfix + * mtrr atomicity fix + * vanishing ioctl handler debugging + * libata: always use polling SETXFER + * Linux 2.6.22-rc4 + * [SPARC64]: Move topology init code into new file, sysfs.c + * [SPARC64]: Export basic cpu properties via sysfs. + * [SPARC64]: Fix service channel hypervisor function names. + * [SPARC64]: Provide mmu statistics via sysfs. + * [SPARC64]: Proper multi-core scheduling support. + * [SPARC64]: Make core and sibling groups equal on UltraSPARC-IV. + * [SPARC64]: Fix {mc,smt}_capable(). + * [SPARC64]: Fill in gaps in non-PCI dma_*() NOP implementation. + * [ATA]: Back out bogus (SPARC64 && !PCI) Kconfig depends. + * [VIDEO]: Fix section mismatch warning in promcon. + * [CIFS] whitespace cleanup + * [ARM] Fix 4417/1: Serial: Fix AMBA drivers locking + * [VIDEO] ffb: The pseudo_palette is only 16 elements long + * [ARM] pxa: fix pxa27x keyboard driver + * [VIDEO] sunxvr2500fb: Fix pseudo_palette array size + * [VIDEO] sunxvr500fb: Fix pseudo_palette array size + * [CIFS] whitespace cleanup part 2 + * [CIFS] Missing flag on negprot needed for some servers to force packet + signing + * [MIPS] Atlas, Malta, SEAD: Remove scroll from interrupt handler. + * [MIPS] Remove duplicate fpu enable hazard code. + * [MIPS] EMMA2RH: remove dead KGDB code + * [MIPS] RM300: Fix MMIO problems by marking the PCI INT ACK region busy + * [MIPS] Fix VGA corruption on RM300C + * [MIPS] Drop __ARCH_WANT_SYS_FADVISE64 + * [MIPS] Make dma_map_sg handle sg elements which are longer than one + page + * [MIPS] Fix some system calls with long long arguments + * [MIPS] Remove prototype for deleted function qemu_handle_int + * [MIPS] Fix some minor typoes in arch/mips/Kconfig. + * [MIPS] Fix warning by moving do_default_vi into CONFIG_CPU_MIPSR2_SRS + * [AGPGART] intel_agp: cleanup intel private data + * [AGPGART] intel_agp: use table for device probe + * [AGPGART] intel_agp: add support for 965GME/GLE + * [AGPGART] intel_agp: add support for 945GME + * [AGPGART] intel_agp: Add support for G33, Q33 and Q35 chipsets + * ocfs2: Fix masklog breakage + * ocfs2: Fix invalid assertion during write on 64k pages + * [POWERPC] pasemi: Fix iommu + 64K PAGE_SIZE bug + * [POWERPC] spufs: Refuse to load the module when not running on cell + * [POWERPC] spufs: Hook up spufs_release_mem + * [POWERPC] spufs: Fix gang destroy leaks + * [POWERPC] spufs: Free mm if spufs_fill_dir() failed + * [POWERPC] spufs: Synchronize pte invalidation vs ps close + * [POWERPC] spufs scheduler: Fix wakeup races + * [POWERPC] Fix pci_setup_phb_io_dynamic for pci_iomap + * [POWERPC] cbe_cpufreq: Limit frequency via cpufreq notifier chain + * [POWERPC] scc_sio: Fix link failure + * [POWERPC] Fix typo in booting-without-of-txt section numbering + * [POWERPC] spufs: Don't yield nosched context + * [POWERPC] Add table of contents to booting-without-of.txt + * [POWERPC] spufs: Fix error handling in spufs_fill_dir() + * mmc-atmel: remove linux/mmc/protocol.h dependencies + * au1xmmc: Replace C code with call to ARRAY_SIZE() macro. + * mmc: fix broken if clause + * mmc: don't call switch on old cards + * [POWERPC] Fix building of COFF zImages + * checkpatch.pl: should be executable + * Restrict clearing TIF_SIGPENDING + * mlx4_core: Fix CQ context layout + * mlx4_core: Initialize ctx_list and ctx_lock earlier + * mlx4_core: Free catastrophic error MSI-X interrupt with correct dev_id + * IB/mthca, mlx4_core: Fix typo in comment + * [BNX2]: Fix netdev watchdog on 5708. + * [BNX2]: Add missing wait in bnx2_init_5709_context(). + * [BNX2]: Enable DMA on 5709. + * [BNX2]: Fix occasional counter corruption on 5708. + * [BNX2]: Update version and reldate. + * [TCP]: Honour sk_bound_dev_if in tcp_v4_send_ack + * [IPV4]: Only panic if inetdev_init fails for loopback + * [IPV4]: Convert IPv4 devconf to an array + * [IPV4]: Add default config support after inetdev_init + * [IPV4]: Restore old behaviour of default config values + * [RFKILL]: Make rfkill->name const + * [TCP]: Use LIMIT_NETDEBUG in tcp_retransmit_timer(). + * [TCP] tcp_probe: Attach printf attribute properly to printl(). + * [NETLINK]: Mark netlink policies const + * [RTNETLINK]: ifindex 0 does not exist + * [NETFILTER]: nf_conntrack: fix helper module unload races + * [NETFILTER]: ip_tables: fix compat related crash + * [NETFILTER]: nf_conntrack_amanda: fix textsearch_prepare() error check + * [AF_UNIX]: Fix stream recvmsg() race. + * [UDP]: Revert 2-pass hashing changes. + * [NET]: Avoid duplicate netlink notification when changing link state + * [NET_SCHED]: Fix filter double free + * xfrm: Add security check before flushing SAD/SPD + * [SPARC64]: Fix 2 bugs in PCI Sabre bus scanning. + * [SPARC64]: Fix SBUS IRQ regression caused by PCI-E driver. + * frv: build fix + * enable interrupts in user path of page fault. + * RAMFS NOMMU: missed POSIX UID/GID inode attribute checking + * [SPARC64]: Include instead of . + * [SPARC64]: Handle PCI bridges without 'ranges' property. + * mlx4_core: Check firmware command interface revision + * mlx4_core: Don't set MTT address in dMPT entries with PA set + * IB/mlx4: Fix zeroing of rnr_retry value in ib_modify_qp() + * RDMA/cma: Fix initialization of next_port + * IB/mlx4: Make sure RQ allocation is always valid + * splice: move inode size check into generic_file_splice_read() + * splice: remove do_splice_direct() symbol export + * pipe: move pipe_inode_info structure decleration up before it's used + * splice: move balance_dirty_pages_ratelimited() outside of splice actor + * splice: __generic_file_splice_read: fix i_size_read() length checks + * splice: __generic_file_splice_read: fix read/truncate race + * V4L/DVB (5702): Fix Kconfig items to avoid linkedition errors + * V4L/DVB (5700): Saa7111: fix picture settings cache bug + * V4L/DVB (5699): Cinergyt2: fix file release handler + * V4L/DVB (5675): Move big PIO accesses from the interrupt handler to a + workhandler + * V4L/DVB (5716): Tda10086,tda826x: fix tuning, STR/SNR values + * V4L/DVB (5720): Usbvision: fix urb allocation and submits + * V4L/DVB (5730): Remove unused V4L2_CAP_VIDEO_OUTPUT_POS + * V4L/DVB (5732): Add ivtv CROPCAP support and fix ivtv S_CROP for video + output. + * V4L/DVB (5736): Add V4L2_FBUF_CAP/FLAG_LOCAL/GLOBAL_INV_ALPHA + * V4L/DVB (5673): Fix audio stuttering for saa711x/ivtv when in radio + mode. + * V4L/DVB (5761): Fix broken b2c2 dependency on non x86 architectures + * V4L/DVB (5751): Ivtv: fix ia64 printk format warnings. + * serverworks: remove crappy code + * serverworks: fix CSB6 tuning logic + * it821x: RAID mode fixes + * ide: HPA detect from resume + * ide: generic IDE PCI driver, add another device exception + * hpt366: disallow Ultra133 for HPT374 + * Add the PATA controller device ID to pci_ids.h for MCP73/MCP77. + * ide: Add the MCP73/77 support to PATA driver + * [CIFS] CIFS should honour umask + * update Documentation/driver-model/platform.txt + * Driver core: keep PHYSDEV for old struct class_device + * Driver core: kill unused code + * kobject: use the proper printk level for kobject error + * firmware: remove orphaned Email + * [IPV4]: Do not remove idev when addresses are cleared + * [NetLabel]: consolidate the struct socket/sock handling to just struct + sock + * [CIPSO]: Fix several unaligned kernel accesses in the CIPSO engine. + * USB: set default y for CONFIG_USB_DEVICE_CLASS + * usblp: Don't let suspend to kill ->used + * USB: usb gadgets avoid le{16,32}_to_cpup() + * USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * USB: cxacru: add Documentation file + * USB: cxacru: create sysfs attributes in atm_start instead of bind + * USB: cxacru: ignore error trying to start ADSL in atm_start + * USB: Fix up bogus bInterval values in endpoint descriptors + * OHCI: Fix machine check in ohci_hub_status_data + * update checkpatch.pl to version 0.03 + * m68knommu: fix ColdFire timer off by 1 + * nommu: report correct errno in message + * loop: preallocate eight loop devices + * document Acked-by: + * update feature-removal-schedule.txt to include deprecated functions + * mount -t tmpfs -o mpol=: check nodes online + * slab: fix alien cache handling + * potential parse error in ifdef part 3 + * SLUB: return ZERO_SIZE_PTR for kmalloc(0) + * uml: fix kernel stack size on x86_64 + * Documentation/atomic_ops.txt typo fix + * Move three functions that are only needed for CONFIG_MEMORY_HOTPLUG + * Char: stallion, don't fail with less than max panels + * Char: stallion, alloc tty before pci devices init + * Char: stallion, proper fail return values + * uml: get declaration of simple_strtoul + * isdn/diva: fix section mismatch + * sata_promise: use TF interface for polling NODATA commands + * rt-mutex: fix stale return value + * rt-mutex: fix chain walk early wakeup bug + * pi-futex: fix exit races and locking problems + * fix sysrq-m oops + * x86_64: oops_begin() fix + * reiserfs: mailing list has moved + * checkpatch: produce fewer lines of output + * MAINTAINERS: corrections + * hexdump: more output formatting + * update checkpatch.pl to version 0.04 + * Protect from multiple inclusion + * [IrDA]: Fix Rx/Tx path race. + * [IrDA]: f-timer reloading when sending rejected frames. + * ibmveth: Fix h_free_logical_lan error on pool resize + * ibmveth: Automatically enable larger rx buffer pools for larger mtu + * typo in via-velocity.c + * NetXen: Fix ping issue after reboot on Blades with 3.4.19 firmware + * NetXen: Fix compile failure seen on PPC architecture + * ehea: Fixed possible kernel panic on VLAN packet recv + * phylib: add RGMII-ID mode to the Marvell m88e1111 PHY to fix broken + ucc_geth + * net: fix typo in drivers/net/usb/Kconfig + * remove unused variable in pata_isapnp + * libata: disable NCQ for HITACHI HTS541680J9SA00/SB21C7EP + * libata: fix probe time irq printouts + * libata: print device model and firmware revision for ATAPI devices + * libata: fix hw_sata_spd_limit initialization + * ahci: Add MCP73/MCP77 support to AHCI driver + * libata-core/sff: Fix multiple assumptions about DMA + * libata: Correct abuse of language + * libata passthru: update protocol numbers + * libata passthru: support PIO multi commands + * libata passthru: map UDMA protocols + * libata passthru: always enforce correct DEV bit + * libata passthru: update cached device paramters + * i915: add new pciids for 945GME, 965GME/GLE + * drm/i915: Add support for the G33, Q33, and Q35 chipsets. + * drm: fix radeon setparam on 32/64 bit systems. + * [ARM] VFP: fix section mismatch error + * libata: force PIO on IOMEGA ZIP 250 ATAPI + * libata: limit post SRST nsect/lbal wait to ~100ms + * Blackfin arch: remove defconfig file + * Blackfin arch: DMA code minor naming convention fix + * Blackfin arch: spelling fixes + * Blackfin arch: fix bug ad1836 fails to build properly for BF533-EZKIT + * Blackfin arch: all symbols were offset by 4k, since we didn't have the + __text label. + * Blackfin arch: mark our memory init functions with __init so they get + freed after init + * Blackfin arch: implement a basic /proc/sram file for L1 allocation + visibility + * Blackfin arch: fixup Blackfin MAINTIANERS team member list + * Blackfin arch: scrub old console defines + * Blackfin arch: update defconfigs + * Blackfin arch: unify differences between our diff head.S files -- no + functional changes + * Blackfin arch: move more of our startup code to .init so it can be + freed once we are up and running + * Blackfin arch: add proper ENDPROC() + * Blackfin arch: try to split up functions like this into smaller units + according to LKML review + * Blackfin arch: fix spelling typo in output + * Blackfin arch: As Mike pointed out range goes form m..MAX_BLACKFIN_GPIO + -1 + * Blackfin arch: add missing gpio.h header to fix compiling in some pm + configurations + * Blackfin arch: add support for Alon Bar-Lev's dynamic kernel + command-line + * Blackfin arch: fix bug can not wakeup from sleep via push buttons + * Blackfin arch: make sure we initialize our L1 Data B section properly + based on the linked kernel + * Blackfin arch: redo our linker script a bit + * Blackfin arch: move HI/LO macros into blackfin.h and punt the rest of + macros.h as it includes VDSP macros we never use + * Blackfin serial driver: hook up our UARTs STP bit with userspaces + CMSPAR + * Blackfin serial driver: ignore framing and parity errors + * Blackfin serial driver: actually implement the break_ctl() function + * Blackfin serial driver: decouple PARODD and CMSPAR checking from PARENB + * Blackfin RTC drivers: update MAINTAINERS information + * Blackfin SPI driver: tweak spi cleanup function to match newer kernel + changes + * [ARM] 4442/1: OSIRIS: Fix CPLD register definitions + * [ARM] 4443/1: OSIRIS: Add watchdog device to machine devices + * [ARM] 4444/2: OSIRIS: CPLD suspend fix + * [ARM] 4445/1: ANUBIS: Fix CPLD registers + * Blackfin SPI driver: fix bug SPI DMA incomplete transmission + * Blackfin SMC91X ethernet supporting driver: SMC91C111 LEDs are note + drived in the kernel like in uboot + * [MIPS] Fix KMODE for the R3000 + * [MIPS] SMTC: Don't set and restore irqregs ptr from self_ipi. + * [MIPS] Always install the DSP exception handler. + * [MIPS] Atlas: Fix build. + * [MIPS] Wire up utimensat, signalfd, timerfd, eventfd + * [MIPS] SMTC: Fix warning. + * [MIPS] SMTC: Don't continue in set_vi_srs_handler on detected bad + arguments. + * [MIPS] SMTC: The MT ASE requires to initialize c0_pagemask and + c0_wired. + * [MIPS] SMTC: Fix build error caused by nonsense code. + * [MIPS] Fix modpost warnings by making start_secondary __cpuinit + * [MIPS] Fix IP27 build + * [MIPS] Fix smp barriers in test_and_{change,clear,set}_bit + * libertas: scan two channels per scan command + * libertas: rename wlan_association_worker + * libertas: a debug output was missing a newline + * libertas: fix removal of all debugfs files + * libertas: remove deprecated pm_register and associated code + * libertas: remove __FILE__ from debug output + * libertas: remove unused/superfluous definitions of DEV_NAME_LEN + * libertas: move vendor & product id's into if_usb.c + * libertas: make libertas_wlan_data_rates static + * libertas: fix scanning from associate path + * libertas: exclude non-used code when PROC_DEBUG is not set + * libertas: make debug configurable + * libertas: tune debug code + * libertas: single out mesh code + * libertas: change debug output of libertas_interrupt() + * libertas: get rid of libertas_sbi_get_priv() + * libertas: fix SSID output + * libertas: changed some occurences of kmalloc() + memset(&a,0,sz) to + kzalloc() + * libertas: move reset_device() code main.c to if_usb.c + * libertas: split wlan_add_card() + * libertas: fixed transmission flow control on the mesh interface + * libertas: fix error handling of card initialization + * libertas: added transmission failures to mesh statistics + * libertas: wakeup both mesh and normal wakeup when getting out of scan + * libertas: indirect all hardware access via hw_XXXX functions + * libertas: move contents of fw.h to decl.h + * libertas: split module into two (libertas.ko and usb8xxx.ko) + * libertas: fix RESET logic at unload time + * libertas: let DRV_NAME be overridable + * libertas: remove unused variables in wlan_dev_t + * libertas: fixed incorrect assigment of fcs errors to frag errors + * libertas: add URB debug info + * libertas: fixed kernel oops on module/card removal + * libertas: call SET_NETDEV_DEV from common code + * libertas: replace 'macaddress' with 'bssid' + * libertas: correctly unregister mesh netdev on error + * libertas: don't tear down netdev in libertas_activate_card + * libertas: version bump (321p0) and cmds update for new fw (5.220.10.p0) + * libertas: updated mesh commands for 5.220.9.p11 + * libertas: make scan result handling more flexible + * libertas: fix 'keep previous scan' behavior + * libertas: cleanup of fwt_list_route processing + * libertas: fix oops on rmmod + * libertas: move channel changing into association framework + * libertas: make association paths consistent + * libertas: use MAC_FMT and MAC_ARG where appropriate + * libertas: use compare_ether_addr() rather than memcmp() where + appropriate + * libertas: fix debug enter/leave prints for + libertas_execute_next_command + * libertas: correctly balance locking in libertas_process_rx_command + * libertas: correct error report paths for wlan_fwt_list_ioctl + * libertas: fix deadlock SIOCGIWSCAN handler + * libertas: fix default adhoc channel + * libertas: honor specific channel requests during association + * libertas: send SIOCGIWSCAN event after partial scans too + * libertas: debug print spacing fixes in assoc.c + * libertas: add more verbose debugging to libertas_cmd_80211_authenticate + * libertas: Make WPA work through supplicant handshake + * libertas: updated readme file + * libertas: make mac address configuration work with mesh interface too + * libertas: split wext for eth and msh + * libertas: support for mesh autostart on firmware 5.220.11 + * libertas: fix character set in README + * libertas: sparse fixes + * libertas: first pass at fixing up endianness issues + * libertas: More endianness fixes. + * libertas: more endianness fixes, in tx.c this time + * libertas: don't byte-swap firmware version number. It's a byte array. + * libertas: fix big-endian associate command. + * libertas: tweak association debug output + * libertas: remove structure WLAN_802_11_SSID and libertas_escape_essid + * libertas: remove WPA_SUPPLICANT structure + * libertas: reduce SSID and BSSID mixed-case abuse + * kbuild: fix sh64 section mismatch problems + * cfg80211: fix signed macaddress in sysfs + * mac80211: fix debugfs tx power reduction output + * mac80211: Don't stop tx queue on master device while scanning. + * Input: usbtouchscreen - fix fallout caused by move from drivers/usb + * Input: i8042 - add ASUS P65UP5 to the noloop list + * Input: i8042 - add ULI EV4873 to noloop list + * [PARISC] remove global_ack_eiem + * libertas: pull current channel from firmware on mesh autostart + * libertas: deauthenticate from AP in channel switch + * libertas: actually send mesh frames to mesh netdev + * libertas: convert libertas_mpp into anycast_mask + * [PPP_MPPE]: Fix "osize too small" check. + * NetXen: Fix link status messages + * myri10ge: limit the number of recoveries + * myri10ge: report when the link partner is running in Myrinet mode + * myri10ge: update driver version + * sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses + * sysfs: fix condition check in sysfs_drop_dentry() + * sysfs: fix race condition around sd->s_dentry, take#2 + * [TCP]: Fix left_out setting during FRTO + * Input: move input-polldev to drivers/input + * [SPARC64]: Wire up cookie based sun4v interrupt registry. + * [SPARC64]: Fix IO/MEM space sizing for PCI. + * [SPARC64]: Really fix parport. + * [SPARC64]: Fix args to sun4v_ldc_revoke(). + * [TCP]: Set initial_ssthresh default to zero in Cubic and BIC. + * mmc-omap: fix sd response type 6 vs. 1 + * mmc: get back read-only switch function + * [SCTP]: Correctly set daddr for IPv6 sockets during peeloff + * [SCTP]: Allow unspecified port in sctp_bindx() + * [SCTP] Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails + * [SCTP] Update pmtu handling to be similar to tcp + * [SCTP] Flag a pmtu change request + * [SCTP] Don't disable PMTU discovery when mtu is small + * [POWERPC] Fix per-cpu allocation on oldworld SMP powermacs + * [POWERPC] Fix console output getting dropped on platforms without + udbg_putc + * [AVR32] ratelimit segfault reporting rate + * [AVR32] gpio_*_cansleep() fix + * [AVR32] STK1000: Set SPI_MODE_3 in the ltv350qv board info + * [AVR32] Define ARCH_KMALLOC_MINALIGN to L1_CACHE_BYTES + * [MIPS] Malta: Fix for SOCitSC based Maltas + * [MIPS] Separate performance counter interrupts + * [MIPS] Fix builds where MSC01E_xxx is undefined. + * [TCP]: Add missing break to TCP option parsing code + * [IPV6] addrconf: Fix IPv6 on tuntap tunnels + * [AGPGART] intel_agp: fix device probe + * KVM: Prevent guest fpu state from leaking into the host + * splice: adjust balance_dirty_pages_ratelimited() call + * splice: fix leak of pages on short splice to pipe + * splice: only check do_wakeup in splice_to_pipe() for a real pipe + * [TCP]: Congestion control API RTT sampling fix + * [TCP]: Fix logic breakage due to DSACK separation + * [RXRPC] net/rxrpc/ar-connection.c: fix NULL dereference + * block: always requeue !fs requests at the front + * mm: Fix memory/cpu hotplug section mismatch and oops. + * Resume from RAM on HPC nx6325 broken + * ide-scsi: fix OOPS in idescsi_expiry() + * fix radeon setparam on 32/64 systems, harder. + * tty: restore locked ioctl file op + * i386: fix NMI watchdog not reserving its MSRs + * i386: use the right wrapper to disable the NMI watchdog + * SLUB slab validation: Alloc while interrupts are disabled must use + GFP_ATOMIC + * Restore shmid as inode# to fix /proc/pid/maps ABI breakage + * i386 mm: use pte_update() in ptep_test_and_clear_dirty() + * cpuset: zero malloc - fix for old cpusets + * toshiba_acpi: fix section mismatch in allyesconfig + * swsusp: Fix userland interface + * perfctr-watchdog: fix interchanged parameters to + release_{evntsel,perfctr}_nmi + * fuse: ->fs_flags fixlet + * md: fix two raid10 bugs + * md: fix bug in error handling during raid1 repair + * spi doc updates + * uml: remove PAGE_SIZE from libc code + * uml: kill x86_64 STACK_TOP_MAX + * random: fix output buffer folding + * Rework ptep_set_access_flags and fix sun4c + * SLUB: minimum alignment fixes + * udf: fix possible leakage of blocks + * hugetlb: fix get_policy for stacked shared memory files + * shm: fix the filename of hugetlb sysv shared memory + * Linux 2.6.22-rc5 + * [GFS2] flush the glock completely in inode_go_sync + * [DLM] fix a couple of races + * [GFS2] kernel changes to support new gfs2_grow command + * [GFS2] Kernel changes to support new gfs2_grow command (part 2) + * [GFS2] use zero_user_page + * [GFS2] Addendum patch 2 for gfs2_grow + * [GFS2] Reduce size of struct gdlm_lock + * [GFS2] Clean up inode number handling + * [GFS2] Quotas non-functional - fix bug + * [DLM] keep dlm from panicing when traversing rsb list in debugfs + * [DLM] block scand during recovery [1/6] + * [DLM] add lock timeouts and warnings [2/6] + * [DLM] dlm_device interface changes [3/6] + * [DLM] cancel in conversion deadlock [4/6] + * [DLM] fix new_lockspace error exit [5/6] + * [DLM] wait for config check during join [6/6] + * [DLM] fix compile breakage + * [GFS2] latest gfs2-nmw headers break userland build + * [DLM] Compile fix + * [DLM] timeout fixes + * [DLM] canceling deadlocked lock + * [DLM] dumping master locks + * [DLM] show default protocol + * [GFS2] Quotas non-functional - fix another bug + * [GFS2] Make the log reserved blocks depend on block size + * [DLM] fix socket shutdown + * [GFS2] fix jdata issues + * [GFS2] Fix sign problem in quota/statfs and cleanup _host structures + * [GFS2] Add nanosecond timestamp feature + * [DLM] fix reference counting + * [DLM] variable allocation + * [GFS2] Fix typo in rename of directories + * [GFS2] Fix bug in error path of inode + * [GFS2] Can't mount GFS2 file system on AoE device + * [GFS2] Recovery for lost unlinked inodes + * [GFS2] gfs2_lookupi() uninitialised var fix + * [GFS2] set plock owner in GETLK info + * [GFS2] return conflicts for GETLK + * [GFS2] Fix deallocation issues + * [DLM] don't require FS flag on all nodes + * [GFS2] Journaled file write/unstuff bug + * [GFS2] Remove bogus '\0' in rgrp.c + * [GFS2] Use zero_user_page() in stuffed_readpage() + * [GFS2] assertion failure after writing to journaled file, umount + * [GFS2] Simplify multiple glock aquisition + * [GFS2] Addendum to the journaled file/unmount patch + + -- Ben Collins Fri, 01 Jun 2007 12:15:58 -0400 + +linux-source-2.6.22 (2.6.22-6.13) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/scripts: Remove all remnants of debconf from control scripts + * build/config: Re-enable paravirt/vmi + * build/config: Build ide-core as a module + * i386/x86_64: Allow disabling the putstr's from compressed boot wrapper + * PM: Do not require dev spew to get PM_DEBUG + * RTC: Ratelimit "lost interrupts" message + * UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * build/d-i: Include ide-core in storage-core udeb, not that it's modular + * build/d-i: Make ide-modules depend on storage-code-modules + * build/config: Enable CONFIG_TIMER_STATS on x86_64. + * build/config: Disable CONFIG_RTC_DRV_CMOS + * build/config: Enable TIMER_STATS everywhere. + * build/config: Enable SND_AC97_POWER_SAVE + - LP: #116679 + * kmod: Improve call_usermodehelper_pipe to handle data close + * coredump: Convert to new call_usermodehelper_pipe symantics + * PPC: Only set hwif stuff when ide-core is non-modular + * PPC/MEDIABAY: Export some functions for modular ide-core/ppc-ide + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * Input: logips2pp - add type 72 (PS/2 TrackMan Marble) + * Input: adbhid - do not access input_dev->private directly + * sh: Shut up compiler warnings in __do_page_fault(). + * sh: Fix up psw build rules for r7780rp. + * sh: Kill off pmb slab cache destructor. + * sh: landisk: rtc-rs5c313 support. + * sh: landisk: Header cleanups. + * input: hp680_ts compile fixes. + * [ARM] 4375/1: sharpsl_pm: Fix compile warnings + * [ARM] 4376/1: Selects GENERIC_GPIO for ARCH_IXP4XX in Kconfig + * [ARM] 4378/1: KS8695: Serial driver fix + * [ARM] Remove Integrator/CP SMP platform support + * [ARM] 4382/1: iop13xx: fix msi support + * [ARM] 4383/1: iop: fix usage of '__init' and 'inline' in iop files + * [ARM] 4384/1: S3C2412/13 SPI registers offset correction + * [ARM] Update ARM syscalls + * [ARM] Silence OMAP kernel configuration warning + * [ARM] gic: Fix gic cascade irq handling + * [ARM] integrator: fix pci_v3 compile error with DEBUG_LL + * [ARM] ARMv6: add CPU_HAS_ASID configuration + * [CRYPTO] padlock: Make CRYPTO_DEV_PADLOCK a tristate again + * [CRYPTO] tcrypt: Add missing error check + * eventfd use waitqueue lock ... + * timerfd use waitqueue lock ... + * [IA64] Fix bogus messages about system calls not implemented. + * [IA64] Yet another section mismatch warning + * Fix roundup_pow_of_two(1) + * Further update of the i386 boot documentation + * cciss: Fix pci_driver.shutdown while device is still active + * Linux v2.6.22-rc2 + * [CRYPTO] api: Read module pointer before freeing algorithm + * powerpc: Fix the MODALIAS generation in modpost for of devices + * kbuild: include limits.h in sumversion.c for PATH_MAX + * kconfig: search harder for curses library in check-lxdialog.sh + * kbuild: make modpost section warnings clearer + * kbuild: make better section mismatch reports on i386, arm and mips + * kbuild: add "Section mismatch" warning whitelist for powerpc + * all-archs: consolidate .text section definition in asm-generic + * all-archs: consolidate .data section definition in asm-generic + * kbuild: introduce __init_refok/__initdata_refok to supress section + mismatch warnings + * init/main: use __init_refok to fix section mismatch + * mm: fix section mismatch warnings + * mm/slab: fix section mismatch warning + * IB/core: Free umem when mm is already gone + * IB/ipath: Fix potential deadlock with multicast spinlocks + * IB/core: Add helpers for uncached GID and P_Key searches + * IB/core: Use start_port() and end_port() + * IPoIB: Handle P_Key table reordering + * IB/ehca: Return proper error code if register_mr fails + * IB/mthca: Fix use-after-free on device restart + * IB/mlx4: Fix check of max_qp_dest_rdma in modify QP + * IB/mthca: Set GRH:HopLimit when building MLX headers + * IB/mlx4: Set GRH:HopLimit when sending globally routed MADs + * IB/mthca: Fix RESET to ERROR transition + * IB/mlx4: Fix RESET to RESET and RESET to ERROR transitions + * mlx4_core: Fix array overrun in dump_dev_cap_flags() + * IB/mlx4: Fix check of opcode in mlx4_ib_post_send() + * [IPV6]: Add ip6_tunnel.h to headers_install + * [RFKILL]: Fix check for correct rfkill allocation + * [NET]: Fix net/core/skbuff.c gcc-3.2.3 compilation error + * [TCP] FRTO: Add missing ECN CWR sending to one of the responses + * [TCP] FRTO: Prevent state inconsistency in corner cases + * [IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all + * [NETFILTER]: nf_conntrack: fix use-after-free in helper destroy + callback invocation + * [NETFILTER]: nf_conntrack_ipv4: fix incorrect #ifdef config name + * [IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr + * [NET]: Fix race condition about network device name allocation. + * IB/mlx4: Pass send queue sizes from userspace to kernel + * [ARM] 4387/1: fix /proc/cpuinfo formatting for pre-ARM7 parts + * [ARM] 4388/1: no need for arm/mm mmap range checks for non-mmu + * [ARM] 4395/1: S3C24XX: add include of to relevant + machines + * [ARM] 4396/1: S3C2443: Add missing HCLK clocks + * [ARM] 4397/1: S3C2443: remove SDI0/1 IRQ ambiguity + * [ARM] 4398/1: S3C2443: Fix watchdog IRQ number + * [ARM] 4399/2: S3C2443: Fix SMDK2443 nand timings + * [ARM] 4400/1: S3C24XX: Add high-speed MMC device definition + * [ARM] at91_adc parenthesis balance + * [ARM] spelling fixes + * IB/mlx4: Check if SRQ is full when posting receive + * spelling fixes: arch/sh/ + * sh: revert addition of page fault notifiers + * sh: Wire up signalfd/timerfd/eventfd syscalls. + * sh: Fix up various compile warnings for SE boards. + * sh: Fix page size alignment in __copy_user_page(). + * sh: Disable psw support for R7785RP. + * fs: Kill sh dependency for binfmt_flat. + * sh: disable genrtc support. + * sh: sr.bl toggling around idle sleep. + * sh: Wire up kdump crash kernel exec in die(). + * sh: Fix clock multiplier on SH7722. + * sh: Fix dreamcast build for IRQ changes. + * [S390] cio: Update documentation. + * [S390] Wire up sys_utimensat. + * [S390] Wire up signald, timerfd and eventfd syscalls. + * [S390] Make use of kretprobe_assert. + * [S390] More verbose show_mem() like other architectures. + * Fix "fs: convert core functions to zero_user_page" + * Detach sched.h from mm.h + * Blackfin arch: Add Workaround for ANOMALY 05000257 + * Blackfin arch: add SPI MMC driver support on bf533-stamp, tested on + STAMP-BF533 + * Blackfin arch: ISP1761 doesn't work for USB flash disk + * Blackfin arch: fix a few random warnings + * Blackfin arch: Add configuration data for ISP176x on BF561 + * Blackfin arch: mark a bunch of local functions as static + * Blackfin arch: Fix reserved map after we changed PORT_H definition + * Blackfin arch: Move write to VR_CTL closer to IDLE + * Blackfin arch: DMA operation cleanup + * Blackfin arch: GPIO fix some defines + * Blackfin arch: fix trace output for FLAT binaries + * Blackfin arch: Fix bug using usb keyboard crashes kernel + * Blackfin arch: initial tepla-bf561 board support + * Blackfin arch: make sure we declare the revid functions as pure (since + they are) + * Blackfin arch: dont clear status register bits in SWRST so we can + actually use it + * Blackfin arch: finish removing p* volatile defines for MMRs + * Blackfin arch: move board specific setup out of common init code and + into the board specific init code + * Blackfin arch: issue reset via SWRST so we dont clobber the watchdog + state + * Blackfin arch: document why we have to touch the UART peripheral in our + boot up code + * Blackfin arch: dma_memcpy borken for > 64K + * Blackfin arch: dont clear the bit that tells coreb to start booting + * Blackfin arch: make sure we use local labels + * Blackfin arch: update blackfin header files to latest one in VDSP. + * Blackfin arch: cache SWRST value at bootup so other things like + watchdog can non-destructively query it + * Blackfin arch: fix signal handling bug + * Blackfin arch: Change NO_ACCESS_CHECK to ACCESS_CHECK + * Blackfin arch: add board default configs to blackfin arch + * Blackfin arch: update defconfig files + * Blackfin arch: update pm.c according to power management API change. + * Blackfin serial driver: fix overhead issue + * Blackfin serial driver: implement support for ignoring parity/break + errors + * Blackfin SPI: cleanup according to David Brownell's review + * x86_64: Update defconfig + * i386: Update defconfig + * x86_64: Support x86_64 in make buildtar + * i386: Fix K8/core2 oprofile on multiple CPUs + * x86_64: Support gcc 5 properly + * i386: Clear MCE flag on AMD K6 + * i386: Fix wrong CPU error message in early boot path + * i386: Enable CX8/PGE CPUID bits early on VIA C3 + * x86_64: early_print kernel console should send CRLF not LFCR + * x86_64: vsyscall time() fix + * i386: fix PGE mask + * LDM: Fix for Windows Vista dynamic disks + * IB/ipoib: Fix typos in error messages + * IPoIB/cm: Fix SRQ WR leak + * IB/cm: Improve local id allocation + * e1000: Don't enable polling in open() (was: e1000: assertion hit in + e1000_clean(), kernel 2.6.21.1) + * declance: Remove a dangling spin_unlock_irq() thingy + * Add constant for FCS/CRC length (frame check sequence) + * ahci: disable 64bit dma on sb600 + * libata: Add Seagate STT20000A to DMA blacklist. + * pata_hpt366: Enable bits are unreliable so don't use them + * ata_piix: clean up + * libata: Kiss post_set_mode goodbye + * libata: Trim trailing whitespace + * partitions/LDM: build fix + * Make 'headerscheck' stop immediately on an error + * Fix headers check fallout + * [POWERPC] Fix smp_call_function to be preempt-safe + * [POWERPC] Add missing pmc_type fields in cpu_table + * [POWERPC] Fix typo: MMCR0_PMA0 != MMCR0_PMAO + * [POWERPC] Fix powerpc vmlinux.lds.S + * [POWERPC] Fix warning in 32-bit builds with CONFIG_HIGHMEM + * libertas: skb dereferenced after netif_rx + * drivers/net/wireless/libertas/fw.c: fix use-before-check + * drivers/net/wireless/libertas/rx.c: fix use-after-free + * [IA64] Improve unwind checking. + * [IA64] Only unwind non-running tasks. + * [IA64] fix kmalloc(0) in arch/ia64/pci/pci.c + * i2c: Legacy i2c drivers shouldn't issue uevents + * i2c-tiny-usb: Fix truncated adapter name + * i2c-s3c2410: Fix build warning + * V4L/DVB (5639): Fix Kconfig dependencies for ivtv + * V4L/DVB (5640): Fix: em28xx shouldn't be selecting VIDEO_BUF + * V4L/DVB (5670): Adding new fields to v4l2_pix_format broke the ABI, + reverted that change + * V4L/DVB (5639a): Fix dst usage count + * V4L/DVB (5630): Dvb-core: Handle failures to create devices + * V4L/DVB (5680): Tuner-simple.c fix suport for SECAM with FI1216MF + * V4L/DVB (5690): Cafe_ccic: Properly power down the sensor + * V4L/DVB (5691): Ov7670: reset clkrc in rgb565 mode + * [IPSEC]: Fix warnings with casting int to pointer + * [AF_RXRPC]: AF_RXRPC depends on IPv4 + * [AF_RXRPC]: Make call state names available if CONFIG_PROC_FS=n + * [RTNETLINK]: Allow changing of subsets of netdevice flags in + rtnl_setlink + * [RTNETLINK]: Remove remains of wireless extensions over rtnetlink + * Input: iforce - fix force feedback not working + * Input: iforce - minor clean-ups + * Input: ALPS - force stream mode + * Input: ucb1400_ts - use sched_setscheduler() + * Input: ucb1x00-ts - remove commented out code + * Input: input-polldev - add module info + * Input: ads7846 - document that it handles tsc2046 too + * Input: ads7846 - SPI_CPHA mode bugfix + * USB: fix omninet memory leak found by coverity + * USB: remove useless check in mos7840 found by coverity + * usb-storage: ignore Sitecom WL-117 USB-WLAN + * USB: fix more ftdi-elan/u132-hcd #include lossage + * USB: handle more rndis_host oddities + * USB: remove usb DocBook warnings + * USB: address FIXME in usbnet w.r.t drivers claiming multiple interfaces + * EHCI: fix problem with BIOS handoff + * USB: more autosuspend timer stuff + * USB: remove unneeded WARN_ON + * USB: New device PID for ftdi_sio driver + * USB: set the correct Interrupt interval in usb_bulk_msg + * USB: fsl_usb2_udc: Fix UMTI_WIDE support and a compile warning + * USB: auerswald: fix file release handler + * USB: Remove duplicate IDs from option card driver + * USB: Deref URB after usbmon is done with it + * USB: remove short initial timeout for device descriptor fetch + * USB: don't try to kzalloc 0 bytes + * USB: Onetouch - switch to using input_dev->dev.parent + * USB: Fix debug output of ark3116 + * USB: usblp: Use correct DMA address in case of probe error + * USB: Fix USB OHCI Subvendor for Toshiba Portege 4000 + * USB: make the autosuspend workqueue thread freezable + * USB: handle errors in power/level attribute + * USB: fix ratelimit call semantics + * USB: ftdi_sio: Add USB Product Id for OpenDCC + * USB: ldusb bugfix + * USB: Add support for Sierra Wireless Aircard 595U + * USB: Add support for Olimex arm-usb-ocd JTAG interface serial port + * IB/mlx4: Don't allocate RQ doorbell if using SRQ + * [IA64] start_secondary() and smp_callin() should be __cpuinit + * add the IDE device ID for ATI SB700 + * ide/pci/serverworks.c: Fix corruption/timeouts with MegaIDE + * Add two missing chipsets to drivers/ide/ide-proc.c + * Match DMA blacklist entries between ide-dma.c and libata-core.c + * ide serverworks warning fixes + * freezer: close potential race between refrigerator and thaw_tasks + * freezer: fix vfork problem + * freezer: take kernel_execve into consideration + * freezer: fix kthread_create vs freezer theoretical race + * freezer: fix PF_NOFREEZE vs freezeable race + * freezer: move frozen_process() to kernel/power/process.c + * Ignore bogus ACPI info for offline CPUs + * SLUB Debug: Fix object size calculation + * fuse: fix mknod of regular file + * mpc52xx_psc_spi: fix it for CONFIG_PPC_MERGE + * spi doc update: describe clock mode bits + * NOHZ: Rate limit the local softirq pending warning output + * genhd: expose AN to user space + * genhd: send async notification on media change + * capability.h warning fix + * spi/spidev: check message size before copying + * uml: improve PTRACE_SYSEMU checking + * prohibit rcutorture from being compiled into the kernel + * Documentation: fix the explanation of Kconfig files + * Avoid zero size allocation in cache_k8_northbridges() + * recalc_sigpending_tsk fixes + * optimize compat_core_sys_select() by a using stack space for small fd + sets + * spi: potential memleak in spidev_ioctl + * fbdev: cleanup of sparc FB options + * pm2fb: RDAC_WR barriers clean up + * pm3fb: various fixes + * w100fb: fix compile warnings + * ps3fb: use FB_SYS_* instead of FB_CFB_* + * imxfb: remove ifdefs + * imxfb: fix memory hole + * Missing 'const' from reiserfs MIN_KEY declaration. + * uselib: add missing MNT_NOEXEC check + * fuse: generic_write_checks() for direct_io + * fuse: delete inode on drop + * fix unused setup_nr_node_ids + * SLUB Debug: fix check for super sized slabs (>512k 64bit, >256k 32bit) + * Char: cyclades, fix deadlock + * simplify cleanup_workqueue_thread() + * phantom: move to unlocked_ioctl + * Misc: phantom, take care of pci posting + * power: Fix sizeof(PAGE_SIZE) typo + * update dontdiff file + * signalfd: retrieve multiple signals with one read() call + * i2o: destroy event queue only when drv->event is set + * i2o: fix notifiers when max_drivers is configured + * i2o: eliminate a peculiar constraint on i2o_max_drivers + * i386, x86-64: show that CONFIG_HOTPLUG_CPU is required for suspend on + SMP + * md: avoid overflow in raid0 calculation with large components + * md: don't write more than is required of the last page of a bitmap + * md: fix bug with linear hot-add and elsewhere + * documentation: Documentation/initrd.txt + * HiSax: fix error checking for hisax_register()] + * applesmc - sensors patch missing from 2.6.22-rc2 + * Off by one in floppy.c + * eCryptfs: delay writing 0's after llseek until write + * document clocksources + * ehci-fsl: fix cache coherency problem on system with large memory + * Prevent going idle with softirq pending + * i386: fix early usage of atomic_add_return and local_add_return on real + i386 + * Documentation/memory-barriers.txt: various fixes + * omap_uwire: SPI_CPHA mode bugfix + * capifunc warning fixes + * drivers/isdn/hardware/eicon/message.c warning fixes + * i386 bigsmp: section mismatch fixes + * boot documentation: clarifications + * mmc: clean up unused parts of block driver + * mmc: mark unmaintained drivers + * mmc: Add maintainers for TI OMAP MMC interface + * mmc: add maintainer for iMX MMC interface + * mmc: add maintainer for ARM Primecell controller + * [CRYPTO] geode: Fix in-place operations and set key + * [Bluetooth] Always send HCI_Reset for Broadcom devices + * [Bluetooth] Fix L2CAP configuration parameter handling + * NFS: Avoid a deadlock situation on write + * NFS: Fix handful of compiler warnings in direct.c + * NFS: Fix nfs_direct_dirty_pages() + * Don't call a warnign a bug. It's a warning. + * [IA64] Fix using uninitialized data in _PDC setup + * [IA64] Cleanup acpi header to reuse the generic _PDC defines + * Documentation: Fix up docs still talking about i_sem + * [IA64] acpi_get_sysname() should be __init + * IB/mlx4: Initialize send queue entry ownership bits + * IB/ehca: Fix number of send WRs reported for new QP + * IPoIB/cm: Fix timeout check in ipoib_cm_dev_stop() + * IPoIB/cm: Drain cq in ipoib_cm_dev_stop() + * ucc_geth: Fix MODULE_DEVICE_TABLE() duplication + * ucc_geth:trivial fix + * asix.c - Add Belkin F5D5055 ids + * fix compiler warning in fixed.c + * remove unnecessary dependency on VIA velocity config + * meth driver renovation + * spidernet: skb used after netif_receive_skb + * chelsio parenthesis fix + * forcedeth: fix cpu irq mask + * [NET_SCHED]: Fix qdisc_restart return value when dequeue is empty + * [IPV6]: Ignore ipv6 events on non-IPV6 capable devices. + * [ATM]: Use mutex instead of binary semaphore in idt77252 driver. + * [DCCP]: Use menuconfig objects. + * [IPVS]: Use menuconfig objects. + * [SCTP]: Use menuconfig objects. + * [TIPC]: Use menuconfig objects. + * [ARCNET]: Use menuconfig objects. + * [TR]: Use menuconfig objects. + * [RTNETLINK]: Fix sending netlink message when replace route. + * [TIPC]: Fixed erroneous introduction of for_each_netdev + * [DCCP]: Fix build warning when debugging is disabled. + * [NET_SCHED]: sch_htb: fix event cache time calculation + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number update + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number calculation + * [NETFILTER]: nf_conntrack_h323: fix ASN.1 types + * [NETFILTER]: nf_conntrack_h323: fix get_h225_addr() for IPv6 address + access + * [NETFILTER]: nf_conntrack_h323: remove unnecessary process of + Information signal + * [NETFILTER]: nf_conntrack_h323: add missing T.120 address in OLCA + * [NETFILTER]: nf_nat_h323: call set_h225_addr instead of + set_h225_addr_hook + * [NET]: "wrong timeout value" in sk_wait_data() v2 + * hpt3x2n: Correct revision boundary + * pata_sis: Fix and clean up some timing setups + * ata_piix: add short 40c quirk for Acer Aspire 2030, take #2 + * libata: don't consider 0xff as port empty if SStatus is available + * libata: -ENODEV during prereset isn't an error + * pata_via: Handle laptops via DMI + * [CASSINI]: Check pci_set_mwi() return value. + * [XFRM]: Allow packet drops during larval state resolution. + * [libata] sata_promise: fix flags typo + * [libata] sata_mv: add TODO list + * Fix build failure for drivers/ata/pata_scc.c + * libata: sata_sis fixes + * [libata] Fix decoding of 6-byte commands + * [libata] sata_via, pata_via: Add PCI IDs. + * ocfs2: trylock in ocfs2_readpage() + * ocfs2: unmap_mapping_range() in ocfs2_truncate() + * ocfs2: use zero_user_page + * ocfs2: fix inode leak + * ocfs2: use generic_segment_checks + * pata: Trivia + * pata_hpt37x: Further improvements based on the IDE updates and vendor + drivers + * fix compat console unimap regression + * Linux 2.6.22-rc3 + + -- Ben Collins Thu, 31 May 2007 12:35:44 -0400 + +linux-source-2.6.22 (2.6.22-5.11) gutsy; urgency=low + + [Ben Collins] + + * build/headers/ppc: Correct asm-ppc -> asm for arch symlink + * build/headers/ia64: Fix find command line to correctly pull in *.lds + files + * Bump ABI + + [Upstream Kernel Changes] + + * [IA64] spelling fixes: arch/ia64/ + * [AVR32] Remove bogus comment in arch/avr32/kernel/irq.c + * [AVR32] optimize pagefault path + * [AVR32] Wire up signalfd, timerfd and eventfd + * [IA64] wire up {signal,timer,event}fd syscalls + * [IA64] kdump on INIT needs multi-nodes sync-up (v.2) + * [IA64] s/scalibility/scalability/ + * [AVR32] Implement platform hooks for atmel_lcdfb driver + * [IA64] Fix section conflict of ia64_mlogbuf_finish + * [SPARC64]: Add hypervisor API negotiation and fix console bugs. + * pata_scc had been missed by ata_std_prereset() switch + * libata: separate out ata_dev_reread_id() + * libata: during revalidation, check n_sectors after device is configured + * libata-acpi: add ATA_FLAG_ACPI_SATA port flag + * libata: fix shutdown warning message printing + * libata: track spindown status and skip spindown_compat if possible + * [ALSA] usb-audio: another Logitech QuickCam ID + * [ALSA] hda-codec - Make the mixer capability check more robust + * [ALSA] ASoC AC97 static GPL symbol fix + * [ALSA] ASoC AC97 device reg bugfix + * [ALSA] hda-codec - Fix ALC882/861VD codec support on some laptops + * [ALSA] version 1.0.14rc4 + * [ALSA] Fix probe of non-PnP ISA devices + * [ALSA] Include quirks from Ubuntu Dapper/Edgy/Feisty + * [ALSA] usbaudio - Coping with short replies in usbmixer + * [IA64] optimize pagefaults a little + * Fix ACPI suspend / device suspend ordering problem + * AFS: write back dirty data on unmount + * SLUB: It is legit to allocate a slab of the maximum permitted size + * slub: don't confuse ctor and dtor + * AFS: Fix afs_prepare_write() + * spi: fix spidev for >sizeof(long)/32 devices + * parport_pc needs dma-mapping.h + * Fix: find_or_create_page skips cpuset memory spreading. + * slob: implement RCU freeing + * Slab allocators: Drop support for destructors + * SLUB: Remove depends on EXPERIMENTAL and !ARCH_USES_SLAB_PAGE_STRUCT + * SLAB: Move two remaining SLAB specific definitions to slab_def.h + * SLUB: Define functions for cpu slab handling instead of using + PageActive + * slab: warn on zero-length allocations + * slub: fix handling of oversized slabs + * SLUB: slabinfo fixes + * SLUB: Do our own flags based on PG_active and PG_error + * Remove SLAB_CTOR_CONSTRUCTOR + * SLUB: Simplify debug code + * Slab allocators: define common size limitations + * acpi: fix potential call to a freed memory section. + * i386/x86-64: fix section mismatch + * Make __vunmap static + * simplify compat_sys_timerfd + * Let smp_call_function_single return -EBUSY on UP + * Refine SCREEN_INFO sanity check for vgacon initialization + * make freezeable workqueues singlethread + * parport: mailing list is subscribers-only + * docbook: make kernel-locking table readable + * gpio interface loosens call restrictions + * rtc-omap build fix + * rtc kconfig clarification + * icom: add new sub-device-id to support new adapter + * make sysctl/kernel/core_pattern and fs/exec.c agree on maximum core + filename size + * ecryptfs: use zero_user_page + * i386: don't check_pgt_cache in flush_tlb_mm + * circular locking dependency found in QUOTA OFF + * swsusp: fix sysfs interface + * Fix page allocation flags in grow_dev_page() + * mm: more rmap checking + * NS16550A: Restore HS settings in EXCR2 on resume + * Fix incorrect prototype for ipxrtr_route_packet() + * sky2: remove Gigabyte 88e8056 restriction + * sky2: PHY register settings + * sky2: keep track of receive alloc failures + * sky2: MIB counter overflow handling + * sky2: remove dual port workaround + * sky2: memory barriers change + * small netdevices.txt fix + * ibm_emac: fix section mismatch warnings + * ibm_emac: improved PHY support + * ibm_emac: fix link speed detection change + * gianfar: Add I/O barriers when touching buffer descriptor ownership. + * spidernet: node-aware skbuff allocation + * NetXen: Fix NetXen driver ping on system-p + * ixgb: don't print error if pci_enable_msi() fails, cleanup minor leak + * e1000: Fix msi enable leak on error, don't print error message, cleanup + * drivers/ata: remove the wildcard from sata_nv driver + * sata_nv: fix fallout of devres conversion + * libata: remove libata.spindown_compat + * sata_via: pcim_iomap_regions() conversion missed BAR5 + + -- Ben Collins Thu, 17 May 2007 14:54:16 -0400 + +linux-source-2.6.22 (2.6.22-4.10) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/config: Disable obsolete tsdev driver. + * build: Add tsdev to list of modules intentionally removed. + * build/headers: Include *.lds files (fixes ia64 headers). + * build/headers: Add arch/powerpc/include/asm symlink to get all headers. + * build/module-check: Fix logic for printed messages. + * build/maintainer: Use linux instead of upstream-linux for local diffs + * build/config: Enable SLUB slab allocator (vs. SLAB). + * build/config: Disable orinoco_nortel, use prefered hostap_plx + * build/config: Disable ir-usb in favor of irda-usb + * build/config: Disable sis5513(ide) in favor of pata_sis(libata) + * build/config: Disable piix(ide) in favour of pata_oldpiix, ata_piix and + pata_mpiix (libata) + * build/config: Disable zaurus driver in favour of the cdc_ether driver + * build/abi: Note a few modules intentionally removed. + * build/config: Disable mxb and dpc7146 driver in favour of hexium_orion + * build/config: Disable usbtest driver (for development only) + * build/config: Disable keyspan driver in favour of keyspan_pda + * build/abi: Add mxb and usbtest to list of removed modules. + + [Upstream Kernel Changes] + + * net: Trivial MLX4_DEBUG dependency fix. + * mlx4_core: Remove unused doorbell_lock + * [CPUFREQ] Support rev H AMD64s in powernow-k8 + * [CPUFREQ] powernow-k7: fix MHz rounding issue with perflib + * [AGPGART] Fix wrong ID in via-agp.c + * sh64: ROUND_UP macro cleanup in arch/sh64/kernel/pci_sh5.c + * spelling fixes: arch/sh64/ + * sh64: Wire up many new syscalls. + * sh64: Fixups for the irq_regs changes. + * sh64: dma-mapping updates. + * sh64: ppoll/pselect6() and restartable syscalls. + * sh64: Fixup sh-sci build. + * sh64: Update cayman defconfig. + * sh64: generic quicklist support. + * sh64: Add .gitignore entry for syscalltab. + * IB/mlx4: Fix uninitialized spinlock for 32-bit archs + * IB/ipath: Shadow the gpio_mask register + * IB/ehca: Serialize hypervisor calls in ehca_register_mr() + * IB/ehca: Correctly set GRH mask bit in ehca_modify_qp() + * IB/ehca: Fix AQP0/1 QP number + * IB/ehca: Remove _irqsave, move #ifdef + * IB/ehca: Beautify sysfs attribute code and fix compiler warnings + * IB/ehca: Disable scaling code by default, bump version number + * RDMA/cma: Simplify device removal handling code + * RDMA/cma: Fix synchronization with device removal in cma_iw_handler + * RDMA/cma: Add check to validate that cm_id is bound to a device + * IB/mthca: Fix posting >255 recv WRs for Tavor + * IB/mthca: Set cleaned CQEs back to HW ownership when cleaning CQ + * IPoIB/cm: Optimize stale connection detection + * [CPUFREQ] Correct revision mask for powernow-k8 + * fix epoll single pass code and add wait-exclusive flag + * epoll locks changes and cleanups + * epoll: fix some comments + * epoll: move kfree inside ep_free + * nommu: add ioremap_page_range() + * h8300 atomic.h update + * alpha: fix hard_smp_processor_id compile error + * m68k: implement __clear_user() + * Remove cpu hotplug defines for __INIT & __INITDATA + * i386: move common parts of smp into their own file + * i386: fix voyager build + * SLUB: CONFIG_LARGE_ALLOCS must consider MAX_ORDER limit + * ll_rw_blk: fix gcc 4.2 warning on current_io_context() + * pasemi_mac: Fix register defines + * pasemi_mac: Interrupt ack fixes + * pasemi_mac: Terminate PCI ID list + * pasemi_mac: Fix local-mac-address parsing + * smc911x: fix compilation breakage + * ucc_geth: eliminate max-speed, change interface-type to + phy-connection-type + * pdc202xx_old: rewrite mode programming code (v2) + * serverworks: PIO mode setup fixes + * sis5513: PIO mode setup fixes + * alim15x3: use ide_tune_dma() + * pdc202xx_new: use ide_tune_dma() + * ide: always disable DMA before tuning it + * cs5530/sc1200: add ->udma_filter methods + * ide: use ide_tune_dma() part #2 + * cs5530/sc1200: DMA support cleanup + * cs5530/sc1200: add ->speedproc support + * sl82c105: add speedproc() method and MWDMA0/1 support + * ide: remove ide_dma_enable() + * ide: add missing validity checks for identify words 62 and 63 + * ide: remove ide_use_dma() + * sl82c105: Switch to ref counting API + * Use menuconfig objects: IDE + * x86: Fix discontigmem + non-HIGHMEM compile + * missing mm.h in fw-ohci + * missing dependencies for USB drivers in input + * missing includes in mlx4 + * em28xx and ivtv should depend on PCI + * rpadlpar breakage - fallout of struct subsystem removal + * m32r: __xchg() should be always_inline + * audit_match_signal() and friends are used only if CONFIG_AUDITSYSCALL + is set + * fix uml-x86_64 + * arm: walk_stacktrace() needs to be exported + + -- Ben Collins Tue, 15 May 2007 10:13:23 -0400 + +linux-source-2.6.22 (2.6.22-3.9) gutsy; urgency=low + + * Fixup firmware-modules -> efi-modules in exclude files. + + [Ben Collins] + + * build/config: Enable CONFIG_TIMER_STATS + * build/config: Disable CONFIG_IRQBALANCE, handled in userspace now + * build: Update modules that have been deprecated + * sparc64: Get some drivers compiling, till patches get upstream. + * powerpc: Add 64-bit cmp op for 32-bit. + * build/config: Disable apm_emu, pasemi_mac and cbe_cpufreq on ppc64 + * build/d-i(cjwatson): Rename firmware-modules to efi-modules + + -- Ben Collins Fri, 11 May 2007 09:38:50 +0200 + +linux-source-2.6.22 (2.6.22-2.7) gutsy; urgency=low + + [Changes for 2.7] + + * Added some more modules going missing to ignore. + * Disable ADB_PMU_LED on powerpc64. FTBFS. + + [Ben Collins] + + * XXX: Well, xen and rt got disabled in this upload. Hopefully things will + get working again soon. + + * build: Add check for nrcpus on buildd's for CONCURRENCY_LEVEL + * build: No longer provide ndiswrapper or ivtv modules (l-u-m does). + * build/d-i: Remove firmware lists, since we no longer supply those udebs + * build: Remove more firmware stuff + * build/control: Build-dep on coreutils + * Update configuration files + * build/custom: Updated xen/rt patches and configs. + * build: Make sure to use /bin/bash for headers_install + * build: Add SHELL=/bin/bash to headers_install + * Update configuration files + * Bump ABI + * Update module lists to match module name changes and merges. + * build/rt: Trimmed down real-time patch from Alessio Igor Bogani. + * Update configuration files + * Update configuration files + * build/rt: Fix typo in diff + * Update configuration files + * build: make explicit binary-headers target + * Update configuration files + * build/control-scripts: Remove debconf from pre-rm script + * build/ia64: Compress and use vmlinuz for target install + * build/config: Diable OSS i810_audio driver (Alsa driver prefered) + * build/config: Disable OSS cs4232 driver (Alsa prefered) + * build/config: Disable OSS via82xx driver (Alsa prefered) + * build/config: Disable OSS trident driver (Alsa prefered) + * build/config: Disable OSS Sound Blaster driver (Alsa prefered) + * build/config: Disable IDE generic, ata_generic prefered + * build/config: Disable siimage, pata_sil680 prefered + * build/module-check: More robust module checking + * build: Call module-check with perl, not $SHELL + * Update configuration files + * build: Fixup calling conventions of module-check + * build: Add modules.ignore from 1.3 revision + * build/config: Disable obsolete MOXA_SMARTIO in favor of new driver. + * build/config: Disable orinoco_cs in favor of hostap_cs + * build/config: Disable orinoco_pci in favor of hostap_pci + * build/config: Disable orinoco_{plx,tmd} in favor of hostap_plx + * build/config: Disable sk98lin in favor of skge + * build: Add more modules intentionally removed since 1.3 + + -- Ben Collins Fri, 27 Apr 2007 09:04:29 -0400 + +linux-source-2.6.22 (2.6.22-1.3) gutsy; urgency=low + + [Ben Collins] + + * build: Only use bzip2 for linux-image, and pre-depend on proper dpkg + + [2.6.22-1.2] + + [Ben Collins] + + * build: Add build-arch target. FTBFS + + [2.6.22-1.1] + + [Ben Collins] + + * debian: New build system, from scratch + * debian: Rename place holder so debian/stamps/ sticks around + * debian: Create stamp-flavours at start of build (for build scripts) + * debian/abi: Add revision 0.0 bootstrap module list. + * debian: Fix backwards logic in module/abi checkers. + * debian: Add arch= to vars.* files + * Update configuration files + * build: Added control scripts for images + * build/config: Disable CONFIG_PARAVIRT for now + * build/config: Enable CONFIG_FB_VESA + * build: Take CONCURRENCY_LEVEL from env if it exists. + * build: Do not print SHAs by default for changelog + * build/config(i386): Disable NO_HZ on all but generic + * build: Implement udeb rules + * build/d-i: Remove speakup-modules udeb + * build/udebs: Fix a couple trivial errors in the build. + * build/config: Disable CONFIG_FB_IMSTT on powerpc64-smp (no NVRAM) + * build/config: Disable some modules for ppc64 that don't use DMA API + * build/config: Yet another module to disable on ppc64 + * build/tests: New test infrastructure + * build: Special kernel build infrastructure + * build: Fix typo from last commit + * build/custom: Move custom files for each flavour into subdir. + * build/config: Disable some drivers on sparc that don't support DMA API + * build/sparc: Add new compress_file config, and use it for sparc + * build: Fix typo in compress_file commit. + * build/schedcfs: Update to v6 of the patch. + * build: Fix control file generation for custom images + * build: Correct message in link-headers + * build: 2.6.21 is released, force our SUBLEVEL to .22 + * build/vars: kvm API is at 4, provide that. + * build/custom: Allow custom builds to override things like build_image + * build/custom: Fix type causing custom rules not to be included. + * build/custom: Hello Xen 3.0.5 + * build/custom: Remove sched-cfs. Superseded in use by rt. + * build/custom: Add 2.6.21-rt1 patch for -rt custom flavour + * build/link-headers: Make sure to copy new files for custom + + -- Ben Collins Fri, 27 Apr 2007 08:29:00 -0400 --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/rules +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/rules @@ -0,0 +1 @@ +# Nothing special here --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/50-cell-usb-workaround-ehci-iso.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/50-cell-usb-workaround-ehci-iso.patch @@ -0,0 +1,84 @@ +From: Masashi Kimoto + +When we use Linux git tree on PS3 we face a error msg from +ps3-ehci-driver, + ps3-ehci-driver sb_04: port 1 resume error -19 + hub 2-0:1.0: hub_port_status failed (err = -32) + ... +Built-in Bluetooth uses a USB isochronous and causes this error. + +USB host controller refers TD after echi driver modify it's Periodic Frame +List. +Because of this, NULLed TD is asscessed and causes USB error. + +In this patch the driver holds the TD while host controller refers the +list after Active bit=0. + +From: Masashi Kimoto +Signed-off-by: Geoff Levand + +--- + drivers/usb/host/ehci-sched.c | 38 ++++++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -21,6 +21,10 @@ + + /*-------------------------------------------------------------------------*/ + ++#ifdef CONFIG_PPC_PS3 ++#include ++#endif ++ + /* + * EHCI scheduled transaction support: interrupt, iso, split iso + * These are called "periodic" transactions in the EHCI spec. +@@ -1168,8 +1172,21 @@ itd_urb_transaction ( + if (likely (!list_empty(&stream->free_list))) { + itd = list_entry (stream->free_list.prev, + struct ehci_itd, itd_list); +- list_del (&itd->itd_list); +- itd_dma = itd->itd_dma; ++#ifdef CONFIG_PPC_PS3 ++ /* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */ ++ if (firmware_has_feature(FW_FEATURE_PS3_LV1) ++ && itd->frame == ((ehci_readl(ehci, ++ &ehci->regs->frame_index) >> 3) ++ % ehci->periodic_size)) ++ itd = NULL; ++ else { ++ list_del (&itd->itd_list); ++ itd_dma = itd->itd_dma; ++ } ++#else ++ list_del (&itd->itd_list); ++ itd_dma = itd->itd_dma; ++#endif + } else + itd = NULL; + +@@ -1784,8 +1801,21 @@ sitd_urb_transaction ( + if (!list_empty(&stream->free_list)) { + sitd = list_entry (stream->free_list.prev, + struct ehci_sitd, sitd_list); +- list_del (&sitd->sitd_list); +- sitd_dma = sitd->sitd_dma; ++#ifdef CONFIG_PPC_PS3 ++ /* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */ ++ if (firmware_has_feature(FW_FEATURE_PS3_LV1) ++ && sitd->frame == ((ehci_readl(ehci, ++ &ehci->regs->frame_index) >> 3) ++ % ehci->periodic_size)) ++ sitd = NULL; ++ else { ++ list_del (&sitd->sitd_list); ++ sitd_dma = sitd->sitd_dma; ++ } ++#else ++ list_del (&sitd->sitd_list); ++ sitd_dma = sitd->sitd_dma; ++#endif + } else + sitd = NULL; + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/00-cell-add-spu-shutdown-method.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/00-cell-add-spu-shutdown-method.patch @@ -0,0 +1,34 @@ +Subject: Cell: Add spu shutdown method + +Add a shutdown method to spu_sysdev_class to allow proper spu resource +cleanup on system shutdown. This is needed to support kexec on the PS3 +platform. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/cell/spu_base.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/platforms/cell/spu_base.c ++++ b/arch/powerpc/platforms/cell/spu_base.c +@@ -462,8 +462,18 @@ void spu_free(struct spu *spu) + } + EXPORT_SYMBOL_GPL(spu_free); + ++static int spu_shutdown(struct sys_device *sysdev) ++{ ++ struct spu *spu = container_of(sysdev, struct spu, sysdev); ++ ++ spu_free_irqs(spu); ++ spu_destroy_spu(spu); ++ return 0; ++} ++ + struct sysdev_class spu_sysdev_class = { +- set_kset_name("spu") ++ set_kset_name("spu"), ++ .shutdown = spu_shutdown, + }; + + int spu_add_sysdev_attr(struct sysdev_attribute *attr) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/35-ps3-gelic.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/35-ps3-gelic.patch @@ -0,0 +1,1857 @@ +Subject: ps3: gigabit ethernet driver +From: Masakazu Mokuno + +Add gigabit ethernet support for PS3. + +Signed-off-by: Masakazu Mokuno +Signed-off-by: Geoff Levand +--- + drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/gelic_net.c | 1575 ++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/net/gelic_net.h | 233 +++++++ + 4 files changed, 1819 insertions(+) + +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -2264,6 +2264,16 @@ config TSI108_ETH + To compile this driver as a module, choose M here: the module + will be called tsi108_eth. + ++config GELIC_NET ++ tristate "PS3 Gigabit Ethernet driver" ++ depends on PPC_PS3 ++ help ++ This driver supports the Gigabit Ethernet device on the ++ PS3 game console. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called gelic_net. ++ + config GIANFAR + tristate "Gianfar Ethernet" + depends on 85xx || 83xx || PPC_86xx +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_TIGON3) += tg3.o + obj-$(CONFIG_BNX2) += bnx2.o + spidernet-y += spider_net.o spider_net_ethtool.o + obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o ++obj-$(CONFIG_GELIC_NET) += gelic_net.o + obj-$(CONFIG_TC35815) += tc35815.o + obj-$(CONFIG_SKGE) += skge.o + obj-$(CONFIG_SKY2) += sky2.o +--- /dev/null ++++ b/drivers/net/gelic_net.c +@@ -0,0 +1,1575 @@ ++/* ++ * PS3 Platfom gelic network driver. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corporation ++ * ++ * this file is based on: spider_net.c ++ * ++ * Network device driver for Cell Processor-Based Blade ++ * ++ * (C) Copyright IBM Corp. 2005 ++ * ++ * Authors : Utz Bacher ++ * Jens Osterkamp ++ * ++ * 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, 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. ++ */ ++ ++#undef DEBUG ++#undef GELIC_RING_CHAIN ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "gelic_net.h" ++ ++#define GELIC_NET_DRV_NAME "Gelic Network Driver" ++#define GELIC_NET_DRV_VERSION "1.0" ++ ++MODULE_AUTHOR("SCE Inc."); ++MODULE_DESCRIPTION("Gelic Network driver"); ++MODULE_LICENSE("GPL"); ++ ++static inline struct device * ctodev(struct gelic_net_card * card) ++{ ++ return &card->dev->core; ++} ++static inline unsigned int bus_id(struct gelic_net_card *card) ++{ ++ return card->dev->bus_id; ++} ++static inline unsigned int dev_id(struct gelic_net_card *card) ++{ ++ return card->dev->dev_id; ++} ++ ++/* set irq_mask */ ++static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask) ++{ ++ int status; ++ ++ status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card), ++ mask, 0); ++ if (status) ++ dev_info(ctodev(card), ++ "lv1_net_set_interrupt_mask failed %d\n", status); ++ return status; ++} ++static inline void gelic_net_rx_irq_on(struct gelic_net_card *card) ++{ ++ gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT); ++} ++static inline void gelic_net_rx_irq_off(struct gelic_net_card *card) ++{ ++ gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT); ++} ++/** ++ * gelic_net_get_descr_status -- returns the status of a descriptor ++ * @descr: descriptor to look at ++ * ++ * returns the status as in the dmac_cmd_status field of the descriptor ++ */ ++static enum gelic_net_descr_status ++gelic_net_get_descr_status(struct gelic_net_descr *descr) ++{ ++ u32 cmd_status; ++ ++ cmd_status = descr->dmac_cmd_status; ++ cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT; ++ return cmd_status; ++} ++ ++/** ++ * gelic_net_set_descr_status -- sets the status of a descriptor ++ * @descr: descriptor to change ++ * @status: status to set in the descriptor ++ * ++ * changes the status to the specified value. Doesn't change other bits ++ * in the status ++ */ ++static void gelic_net_set_descr_status(struct gelic_net_descr *descr, ++ enum gelic_net_descr_status status) ++{ ++ u32 cmd_status; ++ ++ /* read the status */ ++ cmd_status = descr->dmac_cmd_status; ++ /* clean the upper 4 bits */ ++ cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO; ++ /* add the status to it */ ++ cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT; ++ /* and write it back */ ++ descr->dmac_cmd_status = cmd_status; ++ wmb(); ++} ++ ++/** ++ * gelic_net_free_chain - free descriptor chain ++ * @card: card structure ++ * @descr_in: address of desc ++ */ ++static void gelic_net_free_chain(struct gelic_net_card *card, ++ struct gelic_net_descr *descr_in) ++{ ++ struct gelic_net_descr *descr; ++ ++ for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) { ++ dma_unmap_single(ctodev(card), descr->bus_addr, ++ GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); ++ descr->bus_addr = 0; ++ } ++} ++ ++/** ++ * gelic_net_init_chain - links descriptor chain ++ * @card: card structure ++ * @chain: address of chain ++ * @start_descr: address of descriptor array ++ * @no: number of descriptors ++ * ++ * we manage a circular list that mirrors the hardware structure, ++ * except that the hardware uses bus addresses. ++ * ++ * returns 0 on success, <0 on failure ++ */ ++static int gelic_net_init_chain(struct gelic_net_card *card, ++ struct gelic_net_descr_chain *chain, ++ struct gelic_net_descr *start_descr, int no) ++{ ++ int i; ++ struct gelic_net_descr *descr; ++ ++ descr = start_descr; ++ memset(descr, 0, sizeof(*descr) * no); ++ ++ /* set up the hardware pointers in each descriptor */ ++ for (i = 0; i < no; i++, descr++) { ++ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); ++ descr->bus_addr = ++ dma_map_single(ctodev(card), descr, ++ GELIC_NET_DESCR_SIZE, ++ DMA_BIDIRECTIONAL); ++ ++ if (!descr->bus_addr) ++ goto iommu_error; ++ ++ descr->next = descr + 1; ++ descr->prev = descr - 1; ++ } ++ /* make them as ring */ ++ (descr - 1)->next = start_descr; ++ start_descr->prev = (descr - 1); ++ ++ /* chain bus addr of hw descriptor */ ++ descr = start_descr; ++ for (i = 0; i < no; i++, descr++) { ++ descr->next_descr_addr = descr->next->bus_addr; ++ } ++ ++ chain->head = start_descr; ++ chain->tail = start_descr; ++ ++ ++#ifdef GELIC_RING_CHAIN ++ (descr - 1)->next_descr_addr = start_descr->bus_addr; ++#else ++ /* do not chain last hw descriptor */ ++ (descr - 1)->next_descr_addr = 0; ++#endif ++ return 0; ++ ++iommu_error: ++ for (i--, descr--; 0 <= i; i--, descr--) ++ if (descr->bus_addr) ++ dma_unmap_single(ctodev(card), descr->bus_addr, ++ GELIC_NET_DESCR_SIZE, ++ DMA_BIDIRECTIONAL); ++ return -ENOMEM; ++} ++ ++/** ++ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor ++ * @card: card structure ++ * @descr: descriptor to re-init ++ * ++ * return 0 on succes, <0 on failure ++ * ++ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. ++ * Activate the descriptor state-wise ++ */ ++static int gelic_net_prepare_rx_descr(struct gelic_net_card *card, ++ struct gelic_net_descr *descr) ++{ ++ int offset; ++ unsigned int bufsize; ++ ++ if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) { ++ dev_info(ctodev(card), "%s: ERROR status \n", __func__); ++ } ++ /* we need to round up the buffer size to a multiple of 128 */ ++ bufsize = (GELIC_NET_MAX_MTU + GELIC_NET_RXBUF_ALIGN - 1) & ++ (~(GELIC_NET_RXBUF_ALIGN - 1)); ++ ++ /* and we need to have it 128 byte aligned, therefore we allocate a ++ * bit more */ ++ descr->skb = netdev_alloc_skb(card->netdev, ++ bufsize + GELIC_NET_RXBUF_ALIGN - 1); ++ if (!descr->skb) { ++ descr->buf_addr = 0; /* tell DMAC don't touch memory */ ++ dev_info(ctodev(card), ++ "%s:allocate skb failed !!\n", __func__); ++ return -ENOMEM; ++ } ++ descr->buf_size = bufsize; ++ descr->dmac_cmd_status = 0; ++ descr->result_size = 0; ++ descr->valid_size = 0; ++ descr->data_error = 0; ++ ++ offset = ((unsigned long)descr->skb->data) & ++ (GELIC_NET_RXBUF_ALIGN - 1); ++ if (offset) ++ skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); ++ /* io-mmu-map the skb */ ++ descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data, ++ GELIC_NET_MAX_MTU, ++ DMA_BIDIRECTIONAL); ++ wmb(); ++ if (!descr->buf_addr) { ++ dev_kfree_skb_any(descr->skb); ++ descr->skb = NULL; ++ dev_info(ctodev(card), ++ "%s:Could not iommu-map rx buffer\n", __func__); ++ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); ++ return -ENOMEM; ++ } else { ++ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED); ++ return 0; ++ } ++} ++ ++/** ++ * gelic_net_release_rx_chain - free all skb of rx descr ++ * @card: card structure ++ * ++ */ ++static void gelic_net_release_rx_chain(struct gelic_net_card *card) ++{ ++ struct gelic_net_descr * descr = card->rx_chain.head; ++ ++ do { ++ if (descr->skb) { ++ dma_unmap_single(ctodev(card), ++ descr->buf_addr, ++ descr->skb->len, ++ DMA_BIDIRECTIONAL); ++ descr->buf_addr = 0; ++ dev_kfree_skb_any(descr->skb); ++ descr->skb = NULL; ++ descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE; ++ } ++ descr = descr->next; ++ } while (descr != card->rx_chain.head); ++} ++ ++/** ++ * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains ++ * @card: card structure ++ * ++ * fills all descriptors in the rx chain: allocates skbs ++ * and iommu-maps them. ++ * returns 0 on success, <0 on failure ++ */ ++static int gelic_net_fill_rx_chain(struct gelic_net_card *card) ++{ ++ struct gelic_net_descr *descr = card->rx_chain.head; ++ int ret; ++ ++ do { ++ if (!descr->skb) ++ if ((ret = gelic_net_prepare_rx_descr(card, descr))) ++ goto rewind; ++ descr = descr->next; ++ } while (descr != card->rx_chain.head); ++ ++ return 0; ++rewind: ++ gelic_net_release_rx_chain(card); ++ return ret; ++} ++ ++/** ++ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains ++ * @card: card structure ++ * ++ * returns 0 on success, <0 on failure ++ */ ++static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card) ++{ ++ struct gelic_net_descr_chain *chain; ++ int ret; ++ chain = &card->rx_chain; ++ ret = gelic_net_fill_rx_chain(card); ++ chain->head = card->rx_top->prev; /* point to the last */ ++ return ret; ++} ++ ++/** ++ * gelic_net_release_tx_descr - processes a used tx descriptor ++ * @card: card structure ++ * @descr: descriptor to release ++ * ++ * releases a used tx descriptor (unmapping, freeing of skb) ++ */ ++static void gelic_net_release_tx_descr(struct gelic_net_card *card, ++ struct gelic_net_descr *descr) ++{ ++ struct sk_buff *skb; ++ ++ ++ if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) { ++ /* 2nd descriptor */ ++ skb = descr->skb; ++ dma_unmap_single(ctodev(card), descr->buf_addr, skb->len, ++ DMA_BIDIRECTIONAL); ++ dev_kfree_skb_any(skb); ++ } else { ++ dma_unmap_single(ctodev(card), descr->buf_addr, ++ descr->buf_size, DMA_BIDIRECTIONAL); ++ } ++ ++ descr->buf_addr = 0; ++ descr->buf_size = 0; ++ descr->next_descr_addr = 0; ++ descr->result_size = 0; ++ descr->valid_size = 0; ++ descr->data_status = 0; ++ descr->data_error = 0; ++ descr->skb = NULL; ++ ++ /* set descr status */ ++ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE; ++} ++ ++/** ++ * gelic_net_release_tx_chain - processes sent tx descriptors ++ * @card: adapter structure ++ * @stop: net_stop sequence ++ * ++ * releases the tx descriptors that gelic has finished with ++ */ ++static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop) ++{ ++ struct gelic_net_descr_chain *tx_chain; ++ enum gelic_net_descr_status status; ++ int release = 0; ++ ++ for (tx_chain = &card->tx_chain; ++ tx_chain->head != tx_chain->tail && tx_chain->tail; ++ tx_chain->tail = tx_chain->tail->next) { ++ status = gelic_net_get_descr_status(tx_chain->tail); ++ switch (status) { ++ case GELIC_NET_DESCR_RESPONSE_ERROR: ++ case GELIC_NET_DESCR_PROTECTION_ERROR: ++ case GELIC_NET_DESCR_FORCE_END: ++ if (printk_ratelimit()) ++ dev_info(ctodev(card), ++ "%s: forcing end of tx descriptor " \ ++ "with status %x\n", ++ __func__, status); ++ card->netdev_stats.tx_dropped++; ++ break; ++ ++ case GELIC_NET_DESCR_COMPLETE: ++ card->netdev_stats.tx_packets++; ++ card->netdev_stats.tx_bytes += ++ tx_chain->tail->skb->len; ++ break; ++ ++ case GELIC_NET_DESCR_CARDOWNED: ++ /* pending tx request */ ++ default: ++ /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */ ++ goto out; ++ } ++ gelic_net_release_tx_descr(card, tx_chain->tail); ++ release = 1; ++ } ++out: ++ if (!stop && release && netif_queue_stopped(card->netdev)) ++ netif_wake_queue(card->netdev); ++} ++ ++/** ++ * gelic_net_set_multi - sets multicast addresses and promisc flags ++ * @netdev: interface device structure ++ * ++ * gelic_net_set_multi configures multicast addresses as needed for the ++ * netdev interface. It also sets up multicast, allmulti and promisc ++ * flags appropriately ++ */ ++static void gelic_net_set_multi(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ struct dev_mc_list *mc; ++ unsigned int i; ++ uint8_t *p; ++ u64 addr; ++ int status; ++ ++ /* clear all multicast address */ ++ status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card), ++ 0, 1); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_remove_multicast_address failed %d\n", ++ status); ++ /* set broadcast address */ ++ status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), ++ GELIC_NET_BROADCAST_ADDR, 0); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_add_multicast_address failed, %d\n", ++ status); ++ ++ if (netdev->flags & IFF_ALLMULTI ++ || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */ ++ status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), ++ 0, 1); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_add_multicast_address failed, %d\n", ++ status); ++ return; ++ } ++ ++ /* set multicast address */ ++ for (mc = netdev->mc_list; mc; mc = mc->next) { ++ addr = 0; ++ p = mc->dmi_addr; ++ for (i = 0; i < ETH_ALEN; i++) { ++ addr <<= 8; ++ addr |= *p++; ++ } ++ status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), ++ addr, 0); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_add_multicast_address failed, %d\n", ++ status); ++ } ++} ++ ++/** ++ * gelic_net_enable_rxdmac - enables the receive DMA controller ++ * @card: card structure ++ * ++ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN ++ * in the GDADMACCNTR register ++ */ ++static void gelic_net_enable_rxdmac(struct gelic_net_card *card) ++{ ++ int status; ++ ++ status = lv1_net_start_rx_dma(bus_id(card), dev_id(card), ++ card->rx_chain.tail->bus_addr, 0); ++ if (status) ++ printk("lv1_net_start_rx_dma failed, status=%d\n", status); ++} ++ ++/** ++ * gelic_net_disable_rxdmac - disables the receive DMA controller ++ * @card: card structure ++ * ++ * gelic_net_disable_rxdmac terminates processing on the DMA controller by ++ * turing off DMA and issueing a force end ++ */ ++static void gelic_net_disable_rxdmac(struct gelic_net_card *card) ++{ ++ int status; ++ ++ /* this hvc blocks until the DMA in progress really stopped */ ++ status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_stop_rx_dma faild, %d\n", status); ++} ++ ++/** ++ * gelic_net_disable_txdmac - disables the transmit DMA controller ++ * @card: card structure ++ * ++ * gelic_net_disable_txdmac terminates processing on the DMA controller by ++ * turing off DMA and issueing a force end ++ */ ++static void gelic_net_disable_txdmac(struct gelic_net_card *card) ++{ ++ int status; ++ ++ /* this hvc blocks until the DMA in progress really stopped */ ++ status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0); ++ if (status) ++ dev_err(ctodev(card), ++ "lv1_net_stop_tx_dma faild, status=%d\n", status); ++} ++ ++/** ++ * gelic_net_stop - called upon ifconfig down ++ * @netdev: interface device structure ++ * ++ * always returns 0 ++ */ ++static int gelic_net_stop(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ netif_poll_disable(netdev); ++ netif_stop_queue(netdev); ++ ++ /* turn off DMA, force end */ ++ gelic_net_disable_rxdmac(card); ++ gelic_net_disable_txdmac(card); ++ ++ gelic_net_set_irq_mask(card, 0); ++ ++ /* disconnect event port */ ++ free_irq(card->netdev->irq, card->netdev); ++ ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); ++ card->netdev->irq = NO_IRQ; ++ ++ netif_carrier_off(netdev); ++ ++ /* release chains */ ++ gelic_net_release_tx_chain(card, 1); ++ gelic_net_release_rx_chain(card); ++ ++ gelic_net_free_chain(card, card->tx_top); ++ gelic_net_free_chain(card, card->rx_top); ++ ++ return 0; ++} ++ ++/** ++ * gelic_net_get_next_tx_descr - returns the next available tx descriptor ++ * @card: device structure to get descriptor from ++ * ++ * returns the address of the next descriptor, or NULL if not available. ++ */ ++static struct gelic_net_descr * ++gelic_net_get_next_tx_descr(struct gelic_net_card *card) ++{ ++ if (!card->tx_chain.head) ++ return NULL; ++ /* see if we can two consecutive free descrs */ ++ if (card->tx_chain.tail != card->tx_chain.head->next && ++ gelic_net_get_descr_status(card->tx_chain.head) == ++ GELIC_NET_DESCR_NOT_IN_USE && ++ card->tx_chain.tail != card->tx_chain.head->next->next && ++ gelic_net_get_descr_status(card->tx_chain.head->next) == ++ GELIC_NET_DESCR_NOT_IN_USE ) ++ return card->tx_chain.head; ++ else ++ return NULL; ++ ++} ++ ++/** ++ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field ++ * @descr: descriptor structure to fill out ++ * @skb: packet to consider ++ * @middle: middle of frame ++ * ++ * fills out the command and status field of the descriptor structure, ++ * depending on hardware checksum settings. This function assumes a wmb() ++ * has executed before. ++ */ ++static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr, ++ struct sk_buff *skb, int middle) ++{ ++ u32 eofr; ++ ++ if (middle) ++ eofr = 0; ++ else ++ eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME; ++ ++ if (skb->ip_summed != CHECKSUM_PARTIAL) ++ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; ++ else { ++ /* is packet ip? ++ * if yes: tcp? udp? */ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ if (ip_hdr(skb)->protocol == IPPROTO_TCP) ++ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr; ++ else if (ip_hdr(skb)->protocol == IPPROTO_UDP) ++ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr; ++ else /* ++ * the stack should checksum non-tcp and non-udp ++ * packets on his own: NETIF_F_IP_CSUM ++ */ ++ descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr; ++ } ++ } ++} ++ ++/** ++ * gelic_net_prepare_tx_descr_v - get dma address of skb_data ++ * @card: card structure ++ * @descr: descriptor structure ++ * @skb: packet to use ++ * ++ * returns 0 on success, <0 on failure. ++ * ++ */ ++static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card, ++ struct gelic_net_descr *descr, ++ struct sk_buff *skb) ++{ ++ dma_addr_t buf[2]; ++ unsigned int vlan_len; ++ ++ if (skb->len < GELIC_NET_VLAN_POS) ++ return -EINVAL; ++ ++ memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS); ++ if (card->vlan_index != -1) { ++ descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/ ++ descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]); ++ vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */ ++ } else ++ vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */ ++ ++ /* first descr */ ++ buf[0] = dma_map_single(ctodev(card), &descr->vlan, ++ vlan_len, DMA_BIDIRECTIONAL); ++ ++ if (!buf[0]) { ++ dev_err(ctodev(card), ++ "dma map 1 failed (%p, %i). Dropping packet\n", ++ skb->data, vlan_len); ++ return -ENOMEM; ++ } ++ ++ descr->buf_addr = buf[0]; ++ descr->buf_size = vlan_len; ++ descr->skb = skb; /* not used */ ++ descr->data_status = 0; ++ gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */ ++ ++ /* second descr */ ++ card->tx_chain.head = card->tx_chain.head->next; ++ descr->next_descr_addr = descr->next->bus_addr; ++ descr = descr->next; ++ if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) ++ dev_err(ctodev(card),"descr is not free!\n"); /* XXX will be removed */ ++ ++ buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS, ++ skb->len - GELIC_NET_VLAN_POS, ++ DMA_BIDIRECTIONAL); ++ ++ if (!buf[1]) { ++ dev_err(ctodev(card), ++ "dma map 2 failed (%p, %i). Dropping packet\n", ++ skb->data + GELIC_NET_VLAN_POS, ++ skb->len - GELIC_NET_VLAN_POS); ++ dma_unmap_single(ctodev(card), buf[0], vlan_len, ++ DMA_BIDIRECTIONAL); ++ return -ENOMEM; ++ } ++ ++ descr->buf_addr = buf[1]; ++ descr->buf_size = skb->len - GELIC_NET_VLAN_POS; ++ descr->skb = skb; ++ descr->data_status = 0; ++ descr->next_descr_addr= 0; /* terminate hw descr */ ++ gelic_net_set_txdescr_cmdstat(descr,skb, 0); ++ ++ return 0; ++} ++ ++/** ++ * gelic_net_kick_txdma - enables TX DMA processing ++ * @card: card structure ++ * @descr: descriptor address to enable TX processing at ++ * ++ */ ++static int gelic_net_kick_txdma(struct gelic_net_card *card, ++ struct gelic_net_descr *descr) ++{ ++ int status = -ENXIO; ++ int count = 10; ++ ++ if (card->tx_dma_progress) ++ return 0; ++ ++ if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) { ++ card->tx_dma_progress = 1; ++ /* sometimes we need retry here */ ++ while (count--) { ++ status = lv1_net_start_tx_dma(bus_id(card), ++ dev_id(card), ++ descr->bus_addr, 0); ++ if (!status) ++ break; ++ } ++ if (!count) ++ dev_info(ctodev(card), "lv1_net_start_txdma failed," \ ++ "status=%d %#lx\n", ++ status, card->irq_status); ++ } ++ return status; ++} ++ ++/** ++ * gelic_net_xmit - transmits a frame over the device ++ * @skb: packet to send out ++ * @netdev: interface device structure ++ * ++ * returns 0 on success, <0 on failure ++ */ ++static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ struct gelic_net_descr *descr = NULL; ++ int result; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&card->tx_dma_lock, flags); ++ ++ gelic_net_release_tx_chain(card, 0); ++ if (!skb) ++ goto kick; ++ descr = gelic_net_get_next_tx_descr(card); ++ if (!descr) { ++ netif_stop_queue(netdev); ++ spin_unlock_irqrestore(&card->tx_dma_lock, flags); ++ return NETDEV_TX_BUSY; ++ } ++ result = gelic_net_prepare_tx_descr_v(card, descr, skb); ++ ++ if (result) ++ goto error; ++ ++ card->tx_chain.head = card->tx_chain.head->next; ++ ++ if (descr->prev) ++ descr->prev->next_descr_addr = descr->bus_addr; ++kick: ++ wmb(); ++ if (gelic_net_kick_txdma(card, card->tx_chain.tail)) ++ goto error; ++ ++ netdev->trans_start = jiffies; ++ spin_unlock_irqrestore(&card->tx_dma_lock, flags); ++ return NETDEV_TX_OK; ++ ++error: ++ card->netdev_stats.tx_dropped++; ++ spin_unlock_irqrestore(&card->tx_dma_lock, flags); ++ return NETDEV_TX_LOCKED; ++} ++ ++/** ++ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on ++ * @descr: descriptor to process ++ * @card: card structure ++ * ++ * iommu-unmaps the skb, fills out skb structure and passes the data to the ++ * stack. The descriptor state is not changed. ++ */ ++static void gelic_net_pass_skb_up(struct gelic_net_descr *descr, ++ struct gelic_net_card *card) ++{ ++ struct sk_buff *skb; ++ struct net_device *netdev; ++ u32 data_status, data_error; ++ ++ data_status = descr->data_status; ++ data_error = descr->data_error; ++ netdev = card->netdev; ++ /* unmap skb buffer */ ++ skb = descr->skb; ++ dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU, ++ DMA_BIDIRECTIONAL); ++ ++ skb->dev = netdev; ++ skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size); ++ if (!descr->valid_size) ++ dev_info(ctodev(card), "buffer full %x %x %x\n", ++ descr->result_size, descr->buf_size, descr->dmac_cmd_status); ++ ++ descr->skb = NULL; ++ /* ++ * the card put 2 bytes vlan tag in front ++ * of the ethernet frame ++ */ ++ skb_pull(skb, 2); ++ skb->protocol = eth_type_trans(skb, netdev); ++ ++ /* checksum offload */ ++ if (card->rx_csum) { ++ if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) && ++ (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK))) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ } else ++ skb->ip_summed = CHECKSUM_NONE; ++ ++ /* update netdevice statistics */ ++ card->netdev_stats.rx_packets++; ++ card->netdev_stats.rx_bytes += skb->len; ++ ++ /* pass skb up to stack */ ++ netif_receive_skb(skb); ++} ++ ++/** ++ * gelic_net_decode_one_descr - processes an rx descriptor ++ * @card: card structure ++ * ++ * returns 1 if a packet has been sent to the stack, otherwise 0 ++ * ++ * processes an rx descriptor by iommu-unmapping the data buffer and passing ++ * the packet up to the stack ++ */ ++static int gelic_net_decode_one_descr(struct gelic_net_card *card) ++{ ++ enum gelic_net_descr_status status; ++ struct gelic_net_descr_chain *chain = &card->rx_chain; ++ struct gelic_net_descr *descr = chain->tail; ++#ifndef GELIC_RING_CHAIN ++ int dmac_chain_ended; ++#endif ++ ++ status = gelic_net_get_descr_status(descr); ++#ifndef GELIC_RING_CHAIN ++ /* is this descriptor terminated with next_descr == NULL? */ ++ dmac_chain_ended = descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS; ++#endif ++ ++ if (status == GELIC_NET_DESCR_CARDOWNED) { ++ return 0; ++ } ++ if (status == GELIC_NET_DESCR_NOT_IN_USE) { ++ dev_dbg(ctodev(card), "dormant descr? %p\n", descr); ++ return 0; ++ } ++ ++ if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) || ++ (status == GELIC_NET_DESCR_PROTECTION_ERROR) || ++ (status == GELIC_NET_DESCR_FORCE_END)) { ++ dev_info(ctodev(card), "dropping RX descriptor with state %x\n", ++ status); ++ card->netdev_stats.rx_dropped++; ++ goto refill; ++ } ++ ++ if ((status != GELIC_NET_DESCR_COMPLETE) && ++ (status != GELIC_NET_DESCR_FRAME_END)) { ++ dev_dbg(ctodev(card), "RX descriptor with state %x\n", ++ status); ++ goto refill; ++ } ++ ++ /* ok, we've got a packet in descr */ ++ gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */ ++ ++refill: ++#ifndef GELIC_RING_CHAIN ++ descr->next_descr_addr = 0; /* unlink the descr */ ++#endif ++ /* change the descriptor state: */ ++ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); ++ ++ /* refill one desc ++ * FIXME: this can fail, but for now, just leave this ++ * descriptor without skb ++ */ ++ gelic_net_prepare_rx_descr(card, descr); ++ chain->head = descr; ++ chain->tail = descr->next; ++ descr->prev->next_descr_addr = descr->bus_addr; ++ ++#ifndef GELIC_RING_CHAIN ++ if (dmac_chain_ended) { ++ gelic_net_enable_rxdmac(card); ++ dev_dbg(ctodev(card), "reenable rx dma\n"); ++ } ++#endif ++ return 1; ++} ++ ++/** ++ * gelic_net_poll - NAPI poll function called by the stack to return packets ++ * @netdev: interface device structure ++ * @budget: number of packets we can pass to the stack at most ++ * ++ * returns 0 if no more packets available to the driver/stack. Returns 1, ++ * if the quota is exceeded, but the driver has still packets. ++ * ++ */ ++static int gelic_net_poll(struct net_device *netdev, int *budget) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ int packets_to_do, packets_done = 0; ++ int no_more_packets = 0; ++ ++ packets_to_do = min(*budget, netdev->quota); ++ ++ while (packets_to_do) { ++ if (gelic_net_decode_one_descr(card)) { ++ packets_done++; ++ packets_to_do--; ++ } else { ++ /* no more packets for the stack */ ++ no_more_packets = 1; ++ break; ++ } ++ } ++ netdev->quota -= packets_done; ++ *budget -= packets_done; ++ if (no_more_packets) { ++ netif_rx_complete(netdev); ++ gelic_net_rx_irq_on(card); ++ return 0; ++ } else ++ return 1; ++} ++ ++/** ++ * gelic_net_get_stats - get interface statistics ++ * @netdev: interface device structure ++ * ++ * returns the interface statistics residing in the gelic_net_card struct ++ */ ++static struct net_device_stats * gelic_net_get_stats(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ return &card->netdev_stats; ++} ++ ++/** ++ * gelic_net_change_mtu - changes the MTU of an interface ++ * @netdev: interface device structure ++ * @new_mtu: new MTU value ++ * ++ * returns 0 on success, <0 on failure ++ */ ++static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) ++{ ++ /* no need to re-alloc skbs or so -- the max mtu is about 2.3k ++ * and mtu is outbound only anyway */ ++ if ((new_mtu < GELIC_NET_MIN_MTU) || ++ (new_mtu > GELIC_NET_MAX_MTU)) { ++ return -EINVAL; ++ } ++ netdev->mtu = new_mtu; ++ return 0; ++} ++ ++/** ++ * gelic_net_interrupt - event handler for gelic_net ++ */ ++static irqreturn_t gelic_net_interrupt(int irq, void *ptr) ++{ ++ unsigned long flags; ++ struct net_device *netdev = ptr; ++ struct gelic_net_card *card = netdev_priv(netdev); ++ u64 status; ++ ++ status = card->irq_status; ++ ++ if (!status) ++ return IRQ_NONE; ++ ++ if (status & GELIC_NET_RXINT) { ++ gelic_net_rx_irq_off(card); ++ netif_rx_schedule(netdev); ++ } ++ ++ if (status & GELIC_NET_TXINT) { ++ spin_lock_irqsave(&card->tx_dma_lock, flags); ++ card->tx_dma_progress = 0; ++ spin_unlock_irqrestore(&card->tx_dma_lock, flags); ++ /* start pending DMA */ ++ gelic_net_xmit(NULL, netdev); ++ } ++ return IRQ_HANDLED; ++} ++ ++#ifdef CONFIG_NET_POLL_CONTROLLER ++/** ++ * gelic_net_poll_controller - artificial interrupt for netconsole etc. ++ * @netdev: interface device structure ++ * ++ * see Documentation/networking/netconsole.txt ++ */ ++static void gelic_net_poll_controller(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ gelic_net_set_irq_mask(card, 0); ++ gelic_net_interrupt(netdev->irq, netdev); ++ gelic_net_set_irq_mask(card, card->ghiintmask); ++} ++#endif /* CONFIG_NET_POLL_CONTROLLER */ ++ ++/** ++ * gelic_net_open_device - open device and map dma region ++ * @card: card structure ++ */ ++static int gelic_net_open_device(struct gelic_net_card *card) ++{ ++ int result; ++ ++ result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY, ++ &card->netdev->irq); ++ ++ if (result) { ++ dev_info(ctodev(card), ++ "%s:%d: gelic_net_open_device failed (%d)\n", ++ __func__, __LINE__, result); ++ result = -EPERM; ++ goto fail_alloc_irq; ++ } ++ ++ result = request_irq(card->netdev->irq, gelic_net_interrupt, IRQF_DISABLED, ++ "gelic network", card->netdev); ++ ++ if (result) { ++ dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n", ++ __func__, __LINE__, result); ++ goto fail_request_irq; ++ } ++ ++ return 0; ++ ++fail_request_irq: ++ ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); ++ card->netdev->irq = NO_IRQ; ++fail_alloc_irq: ++ return result; ++} ++ ++ ++/** ++ * gelic_net_open - called upon ifonfig up ++ * @netdev: interface device structure ++ * ++ * returns 0 on success, <0 on failure ++ * ++ * gelic_net_open allocates all the descriptors and memory needed for ++ * operation, sets up multicast list and enables interrupts ++ */ ++static int gelic_net_open(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__); ++ ++ gelic_net_open_device(card); ++ ++ if (gelic_net_init_chain(card, &card->tx_chain, ++ card->descr, GELIC_NET_TX_DESCRIPTORS)) ++ goto alloc_tx_failed; ++ if (gelic_net_init_chain(card, &card->rx_chain, ++ card->descr + GELIC_NET_RX_DESCRIPTORS, ++ GELIC_NET_RX_DESCRIPTORS)) ++ goto alloc_rx_failed; ++ ++ /* head of chain */ ++ card->tx_top = card->tx_chain.head; ++ card->rx_top = card->rx_chain.head; ++ dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n", ++ card->rx_top, card->tx_top, sizeof(struct gelic_net_descr), ++ GELIC_NET_RX_DESCRIPTORS); ++ /* allocate rx skbs */ ++ if (gelic_net_alloc_rx_skbs(card)) ++ goto alloc_skbs_failed; ++ ++ card->tx_dma_progress = 0; ++ card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT; ++ ++ gelic_net_set_irq_mask(card, card->ghiintmask); ++ gelic_net_enable_rxdmac(card); ++ ++ netif_start_queue(netdev); ++ netif_carrier_on(netdev); ++ netif_poll_enable(netdev); ++ ++ return 0; ++ ++alloc_skbs_failed: ++ gelic_net_free_chain(card, card->rx_top); ++alloc_rx_failed: ++ gelic_net_free_chain(card, card->tx_top); ++alloc_tx_failed: ++ return -ENOMEM; ++} ++ ++#ifdef GELIC_NET_ETHTOOL ++static void gelic_net_get_drvinfo (struct net_device *netdev, ++ struct ethtool_drvinfo *info) ++{ ++ strncpy(info->driver, GELIC_NET_DRV_NAME, sizeof(info->driver) - 1); ++ strncpy(info->version, GELIC_NET_DRV_VERSION, sizeof(info->version) - 1); ++} ++ ++static int gelic_net_get_settings(struct net_device *netdev, ++ struct ethtool_cmd *cmd) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ int status; ++ u64 v1, v2; ++ int speed, duplex; ++ ++ speed = duplex = -1; ++ status = lv1_net_control(bus_id(card), dev_id(card), ++ GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, ++ &v1, &v2); ++ if (status) { ++ /* link down */ ++ } else { ++ if (v1 & GELIC_NET_FULL_DUPLEX) { ++ duplex = DUPLEX_FULL; ++ } else { ++ duplex = DUPLEX_HALF; ++ } ++ ++ if (v1 & GELIC_NET_SPEED_10 ) { ++ speed = SPEED_10; ++ } else if (v1 & GELIC_NET_SPEED_100) { ++ speed = SPEED_100; ++ } else if (v1 & GELIC_NET_SPEED_1000) { ++ speed = SPEED_1000; ++ } ++ } ++ cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | ++ SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | ++ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; ++ cmd->advertising = cmd->supported; ++ cmd->speed = speed; ++ cmd->duplex = duplex; ++ cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ ++ cmd->port = PORT_TP; ++ ++ return 0; ++} ++ ++static u32 gelic_net_get_link(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ int status; ++ u64 v1, v2; ++ int link; ++ ++ status = lv1_net_control(bus_id(card), dev_id(card), ++ GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, ++ &v1, &v2); ++ if (status) ++ return 0; /* link down */ ++ ++ if (v1 & GELIC_NET_LINK_UP) ++ link = 1; ++ else ++ link = 0; ++ ++ return link; ++} ++ ++static int gelic_net_nway_reset(struct net_device *netdev) ++{ ++ if (netif_running(netdev)) { ++ gelic_net_stop(netdev); ++ gelic_net_open(netdev); ++ } ++ return 0; ++} ++ ++static u32 gelic_net_get_tx_csum(struct net_device *netdev) ++{ ++ return (netdev->features & NETIF_F_IP_CSUM) != 0; ++} ++ ++static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data) ++{ ++ if (data) ++ netdev->features |= NETIF_F_IP_CSUM; ++ else ++ netdev->features &= ~NETIF_F_IP_CSUM; ++ ++ return 0; ++} ++ ++static u32 gelic_net_get_rx_csum(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ return card->rx_csum; ++} ++ ++static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ card->rx_csum = data; ++ return 0; ++} ++ ++static struct ethtool_ops gelic_net_ethtool_ops = { ++ .get_drvinfo = gelic_net_get_drvinfo, ++ .get_settings = gelic_net_get_settings, ++ .get_link = gelic_net_get_link, ++ .nway_reset = gelic_net_nway_reset, ++ .get_tx_csum = gelic_net_get_tx_csum, ++ .set_tx_csum = gelic_net_set_tx_csum, ++ .get_rx_csum = gelic_net_get_rx_csum, ++ .set_rx_csum = gelic_net_set_rx_csum, ++}; ++#endif ++ ++/** ++ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout ++ * function (to be called not under interrupt status) ++ * @work: work is context of tx timout task ++ * ++ * called as task when tx hangs, resets interface (if interface is up) ++ */ ++static void gelic_net_tx_timeout_task(struct work_struct *work) ++{ ++ struct gelic_net_card *card = ++ container_of(work, struct gelic_net_card, tx_timeout_task); ++ struct net_device *netdev = card->netdev; ++ ++ dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); ++ ++ if (!(netdev->flags & IFF_UP)) ++ goto out; ++ ++ netif_device_detach(netdev); ++ gelic_net_stop(netdev); ++ ++ gelic_net_open(netdev); ++ netif_device_attach(netdev); ++ ++out: ++ atomic_dec(&card->tx_timeout_task_counter); ++} ++ ++/** ++ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in. ++ * @netdev: interface device structure ++ * ++ * called, if tx hangs. Schedules a task that resets the interface ++ */ ++static void gelic_net_tx_timeout(struct net_device *netdev) ++{ ++ struct gelic_net_card *card; ++ ++ card = netdev_priv(netdev); ++ atomic_inc(&card->tx_timeout_task_counter); ++ if (netdev->flags & IFF_UP) ++ schedule_work(&card->tx_timeout_task); ++ else ++ atomic_dec(&card->tx_timeout_task_counter); ++} ++ ++/** ++ * gelic_net_setup_netdev_ops - initialization of net_device operations ++ * @netdev: net_device structure ++ * ++ * fills out function pointers in the net_device structure ++ */ ++static void gelic_net_setup_netdev_ops(struct net_device *netdev) ++{ ++ netdev->open = &gelic_net_open; ++ netdev->stop = &gelic_net_stop; ++ netdev->hard_start_xmit = &gelic_net_xmit; ++ netdev->get_stats = &gelic_net_get_stats; ++ netdev->set_multicast_list = &gelic_net_set_multi; ++ netdev->change_mtu = &gelic_net_change_mtu; ++ /* tx watchdog */ ++ netdev->tx_timeout = &gelic_net_tx_timeout; ++ netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT; ++ /* NAPI */ ++ netdev->poll = &gelic_net_poll; ++ netdev->weight = GELIC_NET_NAPI_WEIGHT; ++#ifdef GELIC_NET_ETHTOOL ++ netdev->ethtool_ops = &gelic_net_ethtool_ops; ++#endif ++} ++ ++/** ++ * gelic_net_setup_netdev - initialization of net_device ++ * @card: card structure ++ * ++ * Returns 0 on success or <0 on failure ++ * ++ * gelic_net_setup_netdev initializes the net_device structure ++ **/ ++static int gelic_net_setup_netdev(struct gelic_net_card *card) ++{ ++ struct net_device *netdev = card->netdev; ++ struct sockaddr addr; ++ unsigned int i; ++ int status; ++ u64 v1, v2; ++ ++ SET_MODULE_OWNER(netdev); ++ SET_NETDEV_DEV(netdev, &card->dev->core); ++ spin_lock_init(&card->tx_dma_lock); ++ ++ card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT; ++ ++ gelic_net_setup_netdev_ops(netdev); ++ ++ netdev->features = NETIF_F_IP_CSUM; ++ ++ status = lv1_net_control(bus_id(card), dev_id(card), ++ GELIC_NET_GET_MAC_ADDRESS, ++ 0, 0, 0, &v1, &v2); ++ if (status || !is_valid_ether_addr((u8*)&v1)) { ++ dev_info(ctodev(card), ++ "%s:lv1_net_control GET_MAC_ADDR failed %d\n", ++ __func__,status); ++ return -EINVAL; ++ } ++ v1 <<= 16; ++ memcpy(addr.sa_data, &v1, ETH_ALEN); ++ memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN); ++ dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", ++ netdev->dev_addr[0], netdev->dev_addr[1], ++ netdev->dev_addr[2], netdev->dev_addr[3], ++ netdev->dev_addr[4], netdev->dev_addr[5]); ++ ++ card->vlan_index = -1; /* no vlan */ ++ for (i = 0; i < GELIC_NET_VLAN_MAX; i++) { ++ status = lv1_net_control(bus_id(card), dev_id(card), ++ GELIC_NET_GET_VLAN_ID, ++ i + 1, /* index; one based */ ++ 0, 0, &v1, &v2); ++ if (status == GELIC_NET_VLAN_NO_ENTRY) { ++ dev_dbg(ctodev(card), ++ "GELIC_VLAN_ID no entry:%d, VLAN disabled\n", ++ status); ++ card->vlan_id[i] = 0; ++ } else if (status) { ++ dev_dbg(ctodev(card), ++ "%s:GELIC_NET_VLAN_ID faild, status=%d\n", ++ __func__, status); ++ card->vlan_id[i] = 0; ++ } else { ++ card->vlan_id[i] = (u32)v1; ++ dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1); ++ } ++ } ++ if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) ++ card->vlan_index = GELIC_NET_VLAN_WIRED - 1; ++ ++ status = register_netdev(netdev); ++ if (status) { ++ dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n", ++ __func__, status); ++ return status; ++ } ++ ++ return 0; ++} ++ ++/** ++ * gelic_net_alloc_card - allocates net_device and card structure ++ * ++ * returns the card structure or NULL in case of errors ++ * ++ * the card and net_device structures are linked to each other ++ */ ++static struct gelic_net_card * gelic_net_alloc_card(void) ++{ ++ struct net_device *netdev; ++ struct gelic_net_card *card; ++ size_t alloc_size; ++ ++ alloc_size = sizeof (*card) + ++ sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS + ++ sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS; ++ /* ++ * we assume private data is allocated 32 bytes (or more) aligned ++ * so that gelic_net_descr should be 32 bytes aligned. ++ * Current alloc_etherdev() does do it because NETDEV_ALIGN ++ * is 32. ++ * check this assumption here. ++ */ ++ BUILD_BUG_ON(NETDEV_ALIGN < 32); ++ BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8); ++ BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32); ++ ++ netdev = alloc_etherdev(alloc_size); ++ if (!netdev) ++ return NULL; ++ ++ card = netdev_priv(netdev); ++ card->netdev = netdev; ++ INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); ++ init_waitqueue_head(&card->waitq); ++ atomic_set(&card->tx_timeout_task_counter, 0); ++ ++ return card; ++} ++ ++/** ++ * ps3_gelic_driver_probe - add a device to the control of this driver ++ */ ++static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev) ++{ ++ struct gelic_net_card * card; ++ int result; ++ ++ card = gelic_net_alloc_card(); ++ ++ if (!card) { ++ dev_info(&dev->core, "gelic_net_alloc_card failed\n"); ++ result = -ENOMEM; ++ goto fail_alloc_card; ++ } ++ ++ ps3_system_bus_set_driver_data(dev, card); ++ card->dev = dev; ++ ++ result = ps3_open_hv_device(dev); ++ ++ if (result) { ++ dev_dbg(&dev->core, "ps3_open_hv_device failed\n"); ++ goto fail_open; ++ } ++ ++ result = ps3_dma_region_create(dev->d_region); ++ ++ if (result) { ++ dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n", ++ result); ++ BUG_ON("check region type"); ++ goto fail_dma_region; ++ } ++ ++ result = lv1_net_set_interrupt_status_indicator(bus_id(card), ++ dev_id(card), ++ ps3_mm_phys_to_lpar(__pa(&card->irq_status)), ++ 0); ++ ++ if (result) { ++ dev_dbg(&dev->core, ++ "lv1_net_set_interrupt_status_indicator failed: %s\n", ++ ps3_result(result)); ++ result = -EIO; ++ goto fail_status_indicator; ++ } ++ ++ result = gelic_net_setup_netdev(card); ++ ++ if (result) { ++ dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " ++ "(%d)\n", __func__, __LINE__, result); ++ goto fail_setup_netdev; ++ } ++ ++ return 0; ++ ++fail_setup_netdev: ++ lv1_net_set_interrupt_status_indicator(bus_id(card), ++ bus_id(card), ++ 0 , 0); ++fail_status_indicator: ++ ps3_dma_region_free(dev->d_region); ++fail_dma_region: ++ ps3_close_hv_device(dev); ++fail_open: ++ ps3_system_bus_set_driver_data(dev, NULL); ++ free_netdev(card->netdev); ++fail_alloc_card: ++ return result; ++} ++ ++/** ++ * ps3_gelic_driver_remove - remove a device from the control of this driver ++ */ ++ ++static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev) ++{ ++ struct gelic_net_card * card; ++ ++ card = ps3_system_bus_get_driver_data(dev); ++ ++ wait_event(card->waitq, ++ atomic_read(&card->tx_timeout_task_counter) == 0); ++ ++ lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card), ++ 0 , 0); ++ ++ unregister_netdev(card->netdev); ++ free_netdev(card->netdev); ++ ++ ps3_system_bus_set_driver_data(dev, NULL); ++ ++ ps3_dma_region_free(dev->d_region); ++ ++ ps3_close_hv_device(dev); ++ ++ return 0; ++} ++ ++static struct ps3_system_bus_driver ps3_gelic_driver = { ++ .match_id = PS3_MATCH_ID_GELIC, ++ .probe = ps3_gelic_driver_probe, ++ .remove = ps3_gelic_driver_remove, ++ .shutdown = ps3_gelic_driver_remove, ++ .core.name = "ps3_gelic_driver", ++ .core.owner = THIS_MODULE, ++}; ++ ++static int __init ps3_gelic_driver_init (void) ++{ ++ return firmware_has_feature(FW_FEATURE_PS3_LV1) ++ ? ps3_system_bus_driver_register(&ps3_gelic_driver) ++ : -ENODEV; ++} ++ ++static void __exit ps3_gelic_driver_exit (void) ++{ ++ ps3_system_bus_driver_unregister(&ps3_gelic_driver); ++} ++ ++module_init (ps3_gelic_driver_init); ++module_exit (ps3_gelic_driver_exit); ++ ++MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC); ++ +--- /dev/null ++++ b/drivers/net/gelic_net.h +@@ -0,0 +1,233 @@ ++/* ++ * PS3 Platfom gelic network driver. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corporation. ++ * ++ * this file is based on: spider_net.h ++ * ++ * Network device driver for Cell Processor-Based Blade ++ * ++ * (C) Copyright IBM Corp. 2005 ++ * ++ * Authors : Utz Bacher ++ * Jens Osterkamp ++ * ++ * 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, 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. ++ */ ++#ifndef _GELIC_NET_H ++#define _GELIC_NET_H ++ ++#define GELIC_NET_DRV_NAME "Gelic Network Driver" ++#define GELIC_NET_DRV_VERSION "1.0" ++ ++#define GELIC_NET_ETHTOOL /* use ethtool */ ++ ++/* ioctl */ ++#define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0) ++#define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1) ++ ++/* descriptors */ ++#define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */ ++#define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */ ++ ++#define GELIC_NET_MAX_MTU 2308 ++#define GELIC_NET_MIN_MTU 64 ++#define GELIC_NET_RXBUF_ALIGN 128 ++#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */ ++#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ ++#define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS) ++#define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL ++#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2) ++#define GELIC_NET_VLAN_MAX 4 ++#define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */ ++ ++enum gelic_net_int0_status { ++ GELIC_NET_GDTDCEINT = 24, ++ GELIC_NET_GRFANMINT = 28, ++}; ++ ++/* GHIINT1STS bits */ ++enum gelic_net_int1_status { ++ GELIC_NET_GDADCEINT = 14, ++}; ++ ++/* interrupt mask */ ++#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32)) ++ ++#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32)) ++#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT) ++#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1) ++ ++ /* RX descriptor data_status bits */ ++#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */ ++#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */ ++#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */ ++#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */ ++#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */ ++#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */ ++#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */ ++#define GELIC_NET_RXSESPAH 0x01000000 /* IPsec ESP protocol auth performed */ ++#define GELIC_NET_RXWTPKT 0x00C00000 /* ++ * wakeup trigger packet ++ * 01: Magic Packet (TM) ++ * 10: ARP packet ++ * 11: Multicast MAC addr ++ */ ++#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */ ++/* bit 20..16 reserved */ ++#define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */ ++/* bit 7..0 reserved */ ++ ++#define GELIC_NET_TXDESC_TAIL 0 ++#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK) ++ ++/* RX descriptor data_error bits */ ++/* bit 31 reserved */ ++#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */ ++#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */ ++#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */ ++#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */ ++#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */ ++#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */ ++#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */ ++#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */ ++#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol ++ * processing */ ++#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol ++ * processing */ ++#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */ ++#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */ ++/* bit 18 reserved */ ++#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */ ++#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length ++ * error */ ++#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */ ++#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */ ++/* bit 13..0 reserved */ ++#define GELIC_NET_DATA_ERROR_CHK_MASK (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR) ++ ++ ++/* tx descriptor command and status */ ++#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */ ++#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000 ++#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000 ++#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */ ++ ++#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end ++ * interrupt status */ ++ ++#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */ ++#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000 ++#define GELIC_NET_DESCR_IND_PROC_SHIFT 28 ++#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff ++ ++ ++enum gelic_net_descr_status { ++ GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ ++ GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ ++ GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ ++ GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */ ++ GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ ++ GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ ++ GELIC_NET_DESCR_NOT_IN_USE /* any other value */ ++}; ++/* for lv1_net_control */ ++#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001 ++#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002 ++#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003 ++#define GELIC_NET_GET_VLAN_ID 0x0000000000000004 ++ ++#define GELIC_NET_LINK_UP 0x0000000000000001 ++#define GELIC_NET_FULL_DUPLEX 0x0000000000000002 ++#define GELIC_NET_AUTO_NEG 0x0000000000000004 ++#define GELIC_NET_SPEED_10 0x0000000000000010 ++#define GELIC_NET_SPEED_100 0x0000000000000020 ++#define GELIC_NET_SPEED_1000 0x0000000000000040 ++ ++#define GELIC_NET_VLAN_ALL 0x0000000000000001 ++#define GELIC_NET_VLAN_WIRED 0x0000000000000002 ++#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003 ++#define GELIC_NET_VLAN_PSP 0x0000000000000004 ++#define GELIC_NET_VLAN_PORT0 0x0000000000000010 ++#define GELIC_NET_VLAN_PORT1 0x0000000000000011 ++#define GELIC_NET_VLAN_PORT2 0x0000000000000012 ++#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013 ++#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014 ++#define GELIC_NET_VLAN_NO_ENTRY -6 ++ ++#define GELIC_NET_PORT 2 /* for port status */ ++ ++/* size of hardware part of gelic descriptor */ ++#define GELIC_NET_DESCR_SIZE (32) ++struct gelic_net_descr { ++ /* as defined by the hardware */ ++ u32 buf_addr; ++ u32 buf_size; ++ u32 next_descr_addr; ++ u32 dmac_cmd_status; ++ u32 result_size; ++ u32 valid_size; /* all zeroes for tx */ ++ u32 data_status; ++ u32 data_error; /* all zeroes for tx */ ++ ++ /* used in the driver */ ++ struct sk_buff *skb; ++ dma_addr_t bus_addr; ++ struct gelic_net_descr *next; ++ struct gelic_net_descr *prev; ++ struct vlan_ethhdr vlan; ++} __attribute__((aligned(32))); ++ ++struct gelic_net_descr_chain { ++ /* we walk from tail to head */ ++ struct gelic_net_descr *head; ++ struct gelic_net_descr *tail; ++}; ++ ++struct gelic_net_card { ++ struct net_device *netdev; ++ /* ++ * hypervisor requires irq_status should be ++ * 8 bytes aligned, but u64 member is ++ * always disposed in that manner ++ */ ++ u64 irq_status; ++ u64 ghiintmask; ++ ++ struct ps3_system_bus_device *dev; ++ u32 vlan_id[GELIC_NET_VLAN_MAX]; ++ int vlan_index; ++ ++ struct gelic_net_descr_chain tx_chain; ++ struct gelic_net_descr_chain rx_chain; ++ spinlock_t chain_lock; ++ ++ struct net_device_stats netdev_stats; ++ int rx_csum; ++ spinlock_t tx_dma_lock; ++ int tx_dma_progress; ++ ++ struct work_struct tx_timeout_task; ++ atomic_t tx_timeout_task_counter; ++ wait_queue_head_t waitq; ++ ++ struct gelic_net_descr *tx_top, *rx_top; ++ struct gelic_net_descr descr[0]; ++}; ++ ++ ++extern unsigned long p_to_lp(long pa); ++#endif //_GELIC_NET_H --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/11-ps3-system-bus-rework.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/11-ps3-system-bus-rework.patch @@ -0,0 +1,2082 @@ +Subject: PS3: System-bus rework + +Rework the PS3 system bus to unify device support. + - DMA region sizes must be a power of two + - storage bus DMA updates: + - Small fixes for the PS3 DMA core: + o fix alignment bug + o kill superfluous test + o indentation + o spelling + o export ps3_dma_region_{create,free}() + - ps3_dma_region_init(): + o Add `addr' and `len' parameters, so you can create a DMA region that + does not cover all memory (use `NULL' and `0' to cover all memory). + This is needed because there are not sufficient IOMMU resources to have + all DMA regions cover all memory. + o Uninline + - Added remove and shutdown routines to all drivers. + - Added loadable module support to all drivers. + - Added HV calls for iopte management (needed by sound driver). + +Signed-off-by: MOKUNO Masakazu +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/interrupt.c | 24 - + arch/powerpc/platforms/ps3/mm.c | 621 ++++++++++++++++++++++++++------ + arch/powerpc/platforms/ps3/platform.h | 11 + arch/powerpc/platforms/ps3/system-bus.c | 529 +++++++++++++++++++++++---- + include/asm-powerpc/lv1call.h | 3 + include/asm-powerpc/ps3.h | 149 +++++-- + 6 files changed, 1084 insertions(+), 253 deletions(-) + +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -400,17 +400,15 @@ int ps3_send_event_locally(unsigned int + * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. + * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be + * serviced on. +- * @did: The HV device identifier read from the system repository. +- * @interrupt_id: The device interrupt id read from the system repository. ++ * @dev: The system bus device instance. + * @virq: The assigned Linux virq. + * + * An event irq represents a virtual device interrupt. The interrupt_id + * coresponds to the software interrupt number. + */ + +-int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, +- const struct ps3_device_id *did, unsigned int interrupt_id, +- unsigned int *virq) ++int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, ++ enum ps3_cpu_binding cpu, unsigned int *virq) + { + /* this should go in system-bus.c */ + +@@ -421,8 +419,8 @@ int ps3_sb_event_receive_port_setup(enum + if (result) + return result; + +- result = lv1_connect_interrupt_event_receive_port(did->bus_id, +- did->dev_id, virq_to_hw(*virq), interrupt_id); ++ result = lv1_connect_interrupt_event_receive_port(dev->bus_id, ++ dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); + + if (result) { + pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" +@@ -434,24 +432,24 @@ int ps3_sb_event_receive_port_setup(enum + } + + pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, +- interrupt_id, *virq); ++ dev->interrupt_id, *virq); + + return 0; + } + EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); + +-int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, +- unsigned int interrupt_id, unsigned int virq) ++int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, ++ unsigned int virq) + { + /* this should go in system-bus.c */ + + int result; + + pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, +- interrupt_id, virq); ++ dev->interrupt_id, virq); + +- result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, +- did->dev_id, virq_to_hw(virq), interrupt_id); ++ result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, ++ dev->dev_id, virq_to_hw(virq), dev->interrupt_id); + + if (result) + pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" +--- a/arch/powerpc/platforms/ps3/mm.c ++++ b/arch/powerpc/platforms/ps3/mm.c +@@ -115,7 +116,8 @@ struct map { + }; + + #define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__) +-static void _debug_dump_map(const struct map* m, const char* func, int line) ++static void __maybe_unused _debug_dump_map(const struct map* m, ++ const char* func, int line) + { + DBG("%s:%d: map.total = %lxh\n", func, line, m->total); + DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); +@@ -212,9 +214,15 @@ fail: + + void ps3_mm_vas_destroy(void) + { ++ int result; ++ ++ DBG("%s:%d: map.vas_id = %lu\n", __func__, __LINE__, map.vas_id); ++ + if (map.vas_id) { +- lv1_select_virtual_address_space(0); +- lv1_destruct_virtual_address_space(map.vas_id); ++ result = lv1_select_virtual_address_space(0); ++ BUG_ON(result); ++ result = lv1_destruct_virtual_address_space(map.vas_id); ++ BUG_ON(result); + map.vas_id = 0; + } + } +@@ -275,8 +283,12 @@ zero_region: + + void ps3_mm_region_destroy(struct mem_region *r) + { ++ int result; ++ ++ DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base); + if (r->base) { +- lv1_release_memory(r->base); ++ result = lv1_release_memory(r->base); ++ BUG_ON(result); + r->size = r->base = r->offset = 0; + map.total = map.rm.size; + } +@@ -329,31 +341,34 @@ core_initcall(ps3_mm_add_memory); + /*============================================================================*/ + + /** +- * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address. ++ * dma_sb_lpar_to_bus - Translate an lpar address to ioc mapped bus address. + * @r: pointer to dma region structure + * @lpar_addr: HV lpar address + */ + +-static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r, ++static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r, + unsigned long lpar_addr) + { +- BUG_ON(lpar_addr >= map.r1.base + map.r1.size); +- return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr +- : lpar_addr - map.r1.offset); ++ if (lpar_addr >= map.rm.size) ++ lpar_addr -= map.r1.offset; ++ BUG_ON(lpar_addr < r->offset); ++ BUG_ON(lpar_addr >= r->offset + r->len); ++ return r->bus_addr + lpar_addr - r->offset; + } + + #define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__) +-static void _dma_dump_region(const struct ps3_dma_region *r, const char* func, +- int line) ++static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r, ++ const char* func, int line) + { +- DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, +- r->did.dev_id); ++ DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, ++ r->dev->dev_id); + DBG("%s:%d: page_size %u\n", func, line, r->page_size); + DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); + DBG("%s:%d: len %lxh\n", func, line, r->len); ++ DBG("%s:%d: offset %lxh\n", func, line, r->offset); + } +- +-/** ++ ++ /** + * dma_chunk - A chunk of dma pages mapped by the io controller. + * @region - The dma region that owns this chunk. + * @lpar_addr: Starting lpar address of the area to map. +@@ -381,10 +396,11 @@ static void _dma_dump_chunk (const struc + int line) + { + DBG("%s:%d: r.dev %u:%u\n", func, line, +- c->region->did.bus_id, c->region->did.dev_id); ++ c->region->dev->bus_id, c->region->dev->dev_id); + DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); + DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); + DBG("%s:%d: r.len %lxh\n", func, line, c->region->len); ++ DBG("%s:%d: r.offset %lxh\n", func, line, c->region->offset); + DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr); + DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr); + DBG("%s:%d: c.len %lxh\n", func, line, c->len); +@@ -395,39 +411,68 @@ static struct dma_chunk * dma_find_chunk + { + struct dma_chunk *c; + unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size); +- unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus, ++ 1 << r->page_size); + + list_for_each_entry(c, &r->chunk_list.head, link) { + /* intersection */ +- if (aligned_bus >= c->bus_addr +- && aligned_bus < c->bus_addr + c->len +- && aligned_bus + aligned_len <= c->bus_addr + c->len) { ++ if (aligned_bus >= c->bus_addr && ++ aligned_bus + aligned_len <= c->bus_addr + c->len) + return c; +- } ++ + /* below */ +- if (aligned_bus + aligned_len <= c->bus_addr) { ++ if (aligned_bus + aligned_len <= c->bus_addr) + continue; +- } ++ + /* above */ +- if (aligned_bus >= c->bus_addr + c->len) { ++ if (aligned_bus >= c->bus_addr + c->len) + continue; +- } + + /* we don't handle the multi-chunk case for now */ +- + dma_dump_chunk(c); + BUG(); + } + return NULL; + } + +-static int dma_free_chunk(struct dma_chunk *c) ++static struct dma_chunk * dma_find_chunk_lpar(struct ps3_dma_region *r, ++ unsigned long lpar_addr, unsigned long len) ++{ ++ struct dma_chunk *c; ++ unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar, ++ 1 << r->page_size); ++ ++ list_for_each_entry(c, &r->chunk_list.head, link) { ++ /* intersection */ ++ if (c->lpar_addr <= aligned_lpar && ++ aligned_lpar < c->lpar_addr + c->len) { ++ if (aligned_lpar + aligned_len <= c->lpar_addr + c->len) ++ return c; ++ else { ++ dma_dump_chunk(c); ++ BUG(); ++ } ++ } ++ /* below */ ++ if (aligned_lpar + aligned_len <= c->lpar_addr) { ++ continue; ++ } ++ /* above */ ++ if (c->lpar_addr + c->len <= aligned_lpar) { ++ continue; ++ } ++ } ++ return NULL; ++} ++ ++static int dma_sb_free_chunk(struct dma_chunk *c) + { + int result = 0; + + if (c->bus_addr) { +- result = lv1_unmap_device_dma_region(c->region->did.bus_id, +- c->region->did.dev_id, c->bus_addr, c->len); ++ result = lv1_unmap_device_dma_region(c->region->dev->bus_id, ++ c->region->dev->dev_id, c->bus_addr, c->len); + BUG_ON(result); + } + +@@ -435,8 +480,39 @@ static int dma_free_chunk(struct dma_chu + return result; + } + ++static int dma_ioc0_free_chunk(struct dma_chunk *c) ++{ ++ int result = 0; ++ int iopage; ++ unsigned long offset; ++ struct ps3_dma_region * r = c->region; ++ ++ DBG("%s:start\n", __func__); ++ for (iopage = 0; iopage < (c->len >> r->page_size); iopage++) { ++ offset = (1 << r->page_size) * iopage; ++ /* put INVALID entry */ ++ result = lv1_put_iopte(0, ++ c->bus_addr + offset, ++ c->lpar_addr + offset, ++ r->ioid, ++ 0); ++ DBG("%s: bus=%#lx, lpar=%#lx, ioid=%d\n", __func__, ++ c->bus_addr + offset, ++ c->lpar_addr + offset, ++ r->ioid); ++ ++ if (result) { ++ DBG("%s:%d: lv1_put_iopte failed: %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ } ++ } ++ kfree(c); ++ DBG("%s:end\n", __func__); ++ return result; ++} ++ + /** +- * dma_map_pages - Maps dma pages into the io controller bus address space. ++ * dma_sb_map_pages - Maps dma pages into the io controller bus address space. + * @r: Pointer to a struct ps3_dma_region. + * @phys_addr: Starting physical address of the area to map. + * @len: Length in bytes of the area to map. +@@ -446,8 +522,8 @@ static int dma_free_chunk(struct dma_chu + * make the HV call to add the pages into the io controller address space. + */ + +-static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, +- unsigned long len, struct dma_chunk **c_out) ++static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, ++ unsigned long len, struct dma_chunk **c_out, u64 iopte_flag) + { + int result; + struct dma_chunk *c; +@@ -461,13 +537,13 @@ static int dma_map_pages(struct ps3_dma_ + + c->region = r; + c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); +- c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr); ++ c->bus_addr = dma_sb_lpar_to_bus(r, c->lpar_addr); + c->len = len; + +- result = lv1_map_device_dma_region(c->region->did.bus_id, +- c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len, +- 0xf800000000000000UL); +- ++ BUG_ON(iopte_flag != 0xf800000000000000UL); ++ result = lv1_map_device_dma_region(c->region->dev->bus_id, ++ c->region->dev->dev_id, c->lpar_addr, ++ c->bus_addr, c->len, iopte_flag); + if (result) { + DBG("%s:%d: lv1_map_device_dma_region failed: %s\n", + __func__, __LINE__, ps3_result(result)); +@@ -487,26 +563,119 @@ fail_alloc: + return result; + } + ++static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, ++ unsigned long len, struct dma_chunk **c_out, ++ u64 iopte_flag) ++{ ++ int result; ++ struct dma_chunk *c, *last; ++ int iopage, pages; ++ unsigned long offset; ++ ++ DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__, ++ phys_addr, ps3_mm_phys_to_lpar(phys_addr), len); ++ c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC); ++ ++ if (!c) { ++ result = -ENOMEM; ++ goto fail_alloc; ++ } ++ ++ c->region = r; ++ c->len = len; ++ c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); ++ /* allocate IO address */ ++ if (list_empty(&r->chunk_list.head)) { ++ /* first one */ ++ c->bus_addr = r->bus_addr; ++ } else { ++ /* derive from last bus addr*/ ++ last = list_entry(r->chunk_list.head.next, ++ struct dma_chunk, link); ++ c->bus_addr = last->bus_addr + last->len; ++ DBG("%s: last bus=%#lx, len=%#lx\n", __func__, ++ last->bus_addr, last->len); ++ } ++ ++ /* FIXME: check whether length exceeds region size */ ++ ++ /* build ioptes for the area */ ++ pages = len >> r->page_size; ++ DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__, ++ r->page_size, r->len, pages, iopte_flag); ++ for (iopage = 0; iopage < pages; iopage++) { ++ offset = (1 << r->page_size) * iopage; ++ result = lv1_put_iopte(0, ++ c->bus_addr + offset, ++ c->lpar_addr + offset, ++ r->ioid, ++ iopte_flag); ++ if (result) { ++ printk("%s:%d: lv1_map_device_dma_region failed: %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ goto fail_map; ++ } ++ DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__, ++ iopage, c->bus_addr + offset, c->lpar_addr + offset, ++ r->ioid); ++ } ++ ++ /* be sure that last allocated one is inserted at head */ ++ list_add(&c->link, &r->chunk_list.head); ++ ++ *c_out = c; ++ DBG("%s: end\n", __func__); ++ return 0; ++ ++fail_map: ++ for (iopage--; 0 <= iopage; iopage--) { ++ lv1_put_iopte(0, ++ c->bus_addr + offset, ++ c->lpar_addr + offset, ++ r->ioid, ++ 0); ++ } ++ kfree(c); ++fail_alloc: ++ *c_out = NULL; ++ return result; ++} ++ + /** +- * dma_region_create - Create a device dma region. ++ * dma_sb_region_create - Create a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * + * This is the lowest level dma region create routine, and is the one that + * will make the HV call to create the region. + */ + +-static int dma_region_create(struct ps3_dma_region* r) ++static int dma_sb_region_create(struct ps3_dma_region* r) + { + int result; + +- r->len = _ALIGN_UP(map.total, 1 << r->page_size); ++ pr_info(" -> %s:%d:\n", __func__, __LINE__); ++ ++ BUG_ON(!r); ++ ++ if(!r->dev->bus_id) { ++ pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, ++ r->dev->bus_id, r->dev->dev_id); ++ return 0; ++ } ++ ++ DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__, ++ __LINE__, r->len, r->page_size, r->offset); ++ ++ BUG_ON(!r->len); ++ BUG_ON(!r->page_size); ++ BUG_ON(!r->region_ops); ++ + INIT_LIST_HEAD(&r->chunk_list.head); + spin_lock_init(&r->chunk_list.lock); + +- result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id, +- r->len, r->page_size, r->region_type, &r->bus_addr); +- +- dma_dump_region(r); ++ result = lv1_allocate_device_dma_region(r->dev->bus_id, r->dev->dev_id, ++ roundup_pow_of_two(r->len), r->page_size, r->region_type, ++ &r->bus_addr); + + if (result) { + DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", +@@ -517,6 +686,27 @@ static int dma_region_create(struct ps3_ + return result; + } + ++static int dma_ioc0_region_create(struct ps3_dma_region* r) ++{ ++ int result; ++ ++ INIT_LIST_HEAD(&r->chunk_list.head); ++ spin_lock_init(&r->chunk_list.lock); ++ ++ result = lv1_allocate_io_segment(0, ++ r->len, ++ r->page_size, ++ &r->bus_addr); ++ if (result) { ++ DBG("%s:%d: lv1_allocate_io_segment failed: %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ r->len = r->bus_addr = 0; ++ } ++ DBG("%s: len=%#lx, pg=%d, bus=%#lx\n", __func__, ++ r->len, r->page_size, r->bus_addr); ++ return result; ++} ++ + /** + * dma_region_free - Free a device dma region. + * @r: Pointer to a struct ps3_dma_region. +@@ -525,31 +715,62 @@ static int dma_region_create(struct ps3_ + * will make the HV call to free the region. + */ + +-static int dma_region_free(struct ps3_dma_region* r) ++static int dma_sb_region_free(struct ps3_dma_region* r) + { + int result; + struct dma_chunk *c; + struct dma_chunk *tmp; + ++ BUG_ON(!r); ++ ++ if(!r->dev->bus_id) { ++ pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, ++ r->dev->bus_id, r->dev->dev_id); ++ return 0; ++ } ++ + list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) { + list_del(&c->link); +- dma_free_chunk(c); ++ dma_sb_free_chunk(c); + } + +- result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id, ++ result = lv1_free_device_dma_region(r->dev->bus_id, r->dev->dev_id, + r->bus_addr); + + if (result) + DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", + __func__, __LINE__, ps3_result(result)); + +- r->len = r->bus_addr = 0; ++ r->bus_addr = 0; ++ ++ return result; ++} ++ ++static int dma_ioc0_region_free(struct ps3_dma_region* r) ++{ ++ int result; ++ struct dma_chunk *c, *n; ++ ++ DBG("%s: start\n", __func__); ++ list_for_each_entry_safe(c, n, &r->chunk_list.head, link) { ++ list_del(&c->link); ++ dma_ioc0_free_chunk(c); ++ } ++ ++ result = lv1_release_io_segment(0, r->bus_addr); ++ ++ if (result) ++ DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ ++ r->bus_addr = 0; ++ DBG("%s: end\n", __func__); + + return result; + } + + /** +- * dma_map_area - Map an area of memory into a device dma region. ++ * dma_sb_map_area - Map an area of memory into a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @virt_addr: Starting virtual address of the area to map. + * @len: Length in bytes of the area to map. +@@ -559,16 +780,19 @@ static int dma_region_free(struct ps3_dm + * This is the common dma mapping routine. + */ + +-static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr, +- unsigned long len, unsigned long *bus_addr) ++static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr, ++ unsigned long len, unsigned long *bus_addr, ++ u64 iopte_flag) + { + int result; + unsigned long flags; + struct dma_chunk *c; + unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) + : virt_addr; +- +- *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); ++ unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys, ++ 1 << r->page_size); ++ *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); + + if (!USE_DYNAMIC_DMA) { + unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr); +@@ -588,17 +812,18 @@ static int dma_map_area(struct ps3_dma_r + c = dma_find_chunk(r, *bus_addr, len); + + if (c) { ++ DBG("%s:%d: reusing mapped chunk", __func__, __LINE__); ++ dma_dump_chunk(c); + c->usage_count++; + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return 0; + } + +- result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size), +- _ALIGN_UP(len, 1 << r->page_size), &c); ++ result = dma_sb_map_pages(r, aligned_phys, aligned_len, &c, iopte_flag); + + if (result) { + *bus_addr = 0; +- DBG("%s:%d: dma_map_pages failed (%d)\n", ++ DBG("%s:%d: dma_sb_map_pages failed (%d)\n", + __func__, __LINE__, result); + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return result; +@@ -610,8 +835,57 @@ static int dma_map_area(struct ps3_dma_r + return result; + } + ++static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr, ++ unsigned long len, unsigned long *bus_addr, ++ u64 iopte_flag) ++{ ++ int result; ++ unsigned long flags; ++ struct dma_chunk *c; ++ unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) ++ : virt_addr; ++ unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys, ++ 1 << r->page_size); ++ ++ DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__, ++ virt_addr, len); ++ DBG(KERN_ERR "%s: ph=%#lx a_ph=%#lx a_l=%#lx\n", __func__, ++ phys_addr, aligned_phys, aligned_len); ++ ++ spin_lock_irqsave(&r->chunk_list.lock, flags); ++ c = dma_find_chunk_lpar(r, ps3_mm_phys_to_lpar(phys_addr), len); ++ ++ if (c) { ++ /* FIXME */ ++ BUG(); ++ *bus_addr = c->bus_addr + phys_addr - aligned_phys; ++ c->usage_count++; ++ spin_unlock_irqrestore(&r->chunk_list.lock, flags); ++ return 0; ++ } ++ ++ result = dma_ioc0_map_pages(r, aligned_phys, aligned_len, &c, ++ iopte_flag); ++ ++ if (result) { ++ *bus_addr = 0; ++ DBG("%s:%d: dma_ioc0_map_pages failed (%d)\n", ++ __func__, __LINE__, result); ++ spin_unlock_irqrestore(&r->chunk_list.lock, flags); ++ return result; ++ } ++ *bus_addr = c->bus_addr + phys_addr - aligned_phys; ++ DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__, ++ virt_addr, phys_addr, aligned_phys, *bus_addr); ++ c->usage_count = 1; ++ ++ spin_unlock_irqrestore(&r->chunk_list.lock, flags); ++ return result; ++} ++ + /** +- * dma_unmap_area - Unmap an area of memory from a device dma region. ++ * dma_sb_unmap_area - Unmap an area of memory from a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @bus_addr: The starting ioc bus address of the area to unmap. + * @len: Length in bytes of the area to unmap. +@@ -619,7 +893,7 @@ static int dma_map_area(struct ps3_dma_r + * This is the common dma unmap routine. + */ + +-int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, ++int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, + unsigned long len) + { + unsigned long flags; +@@ -631,7 +905,8 @@ int dma_unmap_area(struct ps3_dma_region + if (!c) { + unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, + 1 << r->page_size); +- unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus, ++ 1 << r->page_size); + DBG("%s:%d: not found: bus_addr %lxh\n", + __func__, __LINE__, bus_addr); + DBG("%s:%d: not found: len %lxh\n", +@@ -647,94 +922,165 @@ int dma_unmap_area(struct ps3_dma_region + + if (!c->usage_count) { + list_del(&c->link); +- dma_free_chunk(c); ++ dma_sb_free_chunk(c); ++ } ++ ++ spin_unlock_irqrestore(&r->chunk_list.lock, flags); ++ return 0; ++} ++ ++int dma_ioc0_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, ++ unsigned long len) ++{ ++ unsigned long flags; ++ struct dma_chunk *c; ++ ++ DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len); ++ spin_lock_irqsave(&r->chunk_list.lock, flags); ++ c = dma_find_chunk(r, bus_addr, len); ++ ++ if (!c) { ++ unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, ++ 1 << r->page_size); ++ unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus, ++ 1 << r->page_size); ++ DBG("%s:%d: not found: bus_addr %lxh\n", ++ __func__, __LINE__, bus_addr); ++ DBG("%s:%d: not found: len %lxh\n", ++ __func__, __LINE__, len); ++ DBG("%s:%d: not found: aligned_bus %lxh\n", ++ __func__, __LINE__, aligned_bus); ++ DBG("%s:%d: not found: aligned_len %lxh\n", ++ __func__, __LINE__, aligned_len); ++ BUG(); ++ } ++ ++ c->usage_count--; ++ ++ if (!c->usage_count) { ++ list_del(&c->link); ++ dma_ioc0_free_chunk(c); + } + + spin_unlock_irqrestore(&r->chunk_list.lock, flags); ++ DBG("%s: end\n", __func__); + return 0; + } + + /** +- * dma_region_create_linear - Setup a linear dma maping for a device. ++ * dma_sb_region_create_linear - Setup a linear dma mapping for a device. + * @r: Pointer to a struct ps3_dma_region. + * + * This routine creates an HV dma region for the device and maps all available + * ram into the io controller bus address space. + */ + +-static int dma_region_create_linear(struct ps3_dma_region *r) ++static int dma_sb_region_create_linear(struct ps3_dma_region *r) + { + int result; +- unsigned long tmp; +- +- /* force 16M dma pages for linear mapping */ ++ unsigned long virt_addr, len, tmp; + +- if (r->page_size != PS3_DMA_16M) { +- pr_info("%s:%d: forcing 16M pages for linear map\n", +- __func__, __LINE__); +- r->page_size = PS3_DMA_16M; ++ if (r->len > 16*1024*1024) { // FIXME ++ /* force 16M dma pages for linear mapping */ ++ if (r->page_size != PS3_DMA_16M) { ++ pr_info("%s:%d: forcing 16M pages for linear map\n", ++ __func__, __LINE__); ++ r->page_size = PS3_DMA_16M; ++ r->len = _ALIGN_UP(r->len, 1 << r->page_size); ++ } + } + +- result = dma_region_create(r); ++ result = dma_sb_region_create(r); + BUG_ON(result); + +- result = dma_map_area(r, map.rm.base, map.rm.size, &tmp); +- BUG_ON(result); +- +- if (USE_LPAR_ADDR) +- result = dma_map_area(r, map.r1.base, map.r1.size, +- &tmp); +- else +- result = dma_map_area(r, map.rm.size, map.r1.size, +- &tmp); ++ if (r->offset < map.rm.size) { ++ /* Map (part of) 1st RAM chunk */ ++ virt_addr = map.rm.base + r->offset; ++ len = map.rm.size - r->offset; ++ if (len > r->len) ++ len = r->len; ++ result = dma_sb_map_area(r, virt_addr, len, &tmp, ++ IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); ++ BUG_ON(result); ++ } + +- BUG_ON(result); ++ if (r->offset + r->len > map.rm.size) { ++ /* Map (part of) 2nd RAM chunk */ ++ virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; ++ len = r->len; ++ if (r->offset >= map.rm.size) ++ virt_addr += r->offset - map.rm.size; ++ else ++ len -= map.rm.size - r->offset; ++ result = dma_sb_map_area(r, virt_addr, len, &tmp, ++ IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); ++ BUG_ON(result); ++ } + + return result; + } + + /** +- * dma_region_free_linear - Free a linear dma mapping for a device. ++ * dma_sb_region_free_linear - Free a linear dma mapping for a device. + * @r: Pointer to a struct ps3_dma_region. + * + * This routine will unmap all mapped areas and free the HV dma region. + */ + +-static int dma_region_free_linear(struct ps3_dma_region *r) ++static int dma_sb_region_free_linear(struct ps3_dma_region *r) + { + int result; ++ unsigned long bus_addr, len, lpar_addr; + +- result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size); +- BUG_ON(result); ++ if (r->offset < map.rm.size) { ++ /* Unmap (part of) 1st RAM chunk */ ++ lpar_addr = map.rm.base + r->offset; ++ len = map.rm.size - r->offset; ++ if (len > r->len) ++ len = r->len; ++ bus_addr = dma_sb_lpar_to_bus(r, lpar_addr); ++ result = dma_sb_unmap_area(r, bus_addr, len); ++ BUG_ON(result); ++ } + +- result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base), +- map.r1.size); +- BUG_ON(result); ++ if (r->offset + r->len > map.rm.size) { ++ /* Unmap (part of) 2nd RAM chunk */ ++ lpar_addr = map.r1.base; ++ len = r->len; ++ if (r->offset >= map.rm.size) ++ lpar_addr += r->offset - map.rm.size; ++ else ++ len -= map.rm.size - r->offset; ++ bus_addr = dma_sb_lpar_to_bus(r, lpar_addr); ++ result = dma_sb_unmap_area(r, bus_addr, len); ++ BUG_ON(result); ++ } + +- result = dma_region_free(r); ++ result = dma_sb_region_free(r); + BUG_ON(result); + + return result; + } + + /** +- * dma_map_area_linear - Map an area of memory into a device dma region. ++ * dma_sb_map_area_linear - Map an area of memory into a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @virt_addr: Starting virtual address of the area to map. + * @len: Length in bytes of the area to map. + * @bus_addr: A pointer to return the starting ioc bus address of the area to + * map. + * +- * This routine just returns the coresponding bus address. Actual mapping ++ * This routine just returns the corresponding bus address. Actual mapping + * occurs in dma_region_create_linear(). + */ + +-static int dma_map_area_linear(struct ps3_dma_region *r, +- unsigned long virt_addr, unsigned long len, unsigned long *bus_addr) ++static int dma_sb_map_area_linear(struct ps3_dma_region *r, ++ unsigned long virt_addr, unsigned long len, unsigned long *bus_addr, ++ u64 iopte_flag) + { + unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) + : virt_addr; +- *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); ++ *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); + return 0; + } + +@@ -744,42 +1090,98 @@ static int dma_map_area_linear(struct ps + * @bus_addr: The starting ioc bus address of the area to unmap. + * @len: Length in bytes of the area to unmap. + * +- * This routine does nothing. Unmapping occurs in dma_region_free_linear(). ++ * This routine does nothing. Unmapping occurs in dma_sb_region_free_linear(). + */ + +-static int dma_unmap_area_linear(struct ps3_dma_region *r, ++static int dma_sb_unmap_area_linear(struct ps3_dma_region *r, + unsigned long bus_addr, unsigned long len) + { + return 0; ++}; ++ ++static const struct ps3_dma_region_ops ps3_dma_sb_region_ops = { ++ .create = dma_sb_region_create, ++ .free = dma_sb_region_free, ++ .map = dma_sb_map_area, ++ .unmap = dma_sb_unmap_area ++}; ++ ++static const struct ps3_dma_region_ops ps3_dma_sb_region_linear_ops = { ++ .create = dma_sb_region_create_linear, ++ .free = dma_sb_region_free_linear, ++ .map = dma_sb_map_area_linear, ++ .unmap = dma_sb_unmap_area_linear ++}; ++ ++static const struct ps3_dma_region_ops ps3_dma_ioc0_region_ops = { ++ .create = dma_ioc0_region_create, ++ .free = dma_ioc0_region_free, ++ .map = dma_ioc0_map_area, ++ .unmap = dma_ioc0_unmap_area ++}; ++ ++int ps3_dma_region_init(struct ps3_system_bus_device *dev, ++ struct ps3_dma_region *r, enum ps3_dma_page_size page_size, ++ enum ps3_dma_region_type region_type, void *addr, unsigned long len) ++{ ++ unsigned long lpar_addr; ++ ++ lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0; ++ ++ r->dev = dev; ++ r->page_size = page_size; ++ r->region_type = region_type; ++ r->offset = lpar_addr; ++ if (r->offset >= map.rm.size) ++ r->offset -= map.r1.offset; ++ r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size); ++ ++ switch (dev->dev_type) { ++ case PS3_DEVICE_TYPE_SB: ++ r->region_ops = (USE_DYNAMIC_DMA) ++ ? &ps3_dma_sb_region_ops ++ : &ps3_dma_sb_region_linear_ops; ++ break; ++ case PS3_DEVICE_TYPE_IOC0: ++ r->region_ops = &ps3_dma_ioc0_region_ops; ++ break; ++ default: ++ BUG(); ++ return -EINVAL; ++ } ++ return 0; + } ++EXPORT_SYMBOL(ps3_dma_region_init); + + int ps3_dma_region_create(struct ps3_dma_region *r) + { +- return (USE_DYNAMIC_DMA) +- ? dma_region_create(r) +- : dma_region_create_linear(r); ++ BUG_ON(!r); ++ BUG_ON(!r->region_ops); ++ BUG_ON(!r->region_ops->create); ++ return r->region_ops->create(r); + } ++EXPORT_SYMBOL(ps3_dma_region_create); + + int ps3_dma_region_free(struct ps3_dma_region *r) + { +- return (USE_DYNAMIC_DMA) +- ? dma_region_free(r) +- : dma_region_free_linear(r); ++ BUG_ON(!r); ++ BUG_ON(!r->region_ops); ++ BUG_ON(!r->region_ops->free); ++ return r->region_ops->free(r); + } ++EXPORT_SYMBOL(ps3_dma_region_free); + + int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, +- unsigned long len, unsigned long *bus_addr) ++ unsigned long len, unsigned long *bus_addr, ++ u64 iopte_flag) + { +- return (USE_DYNAMIC_DMA) +- ? dma_map_area(r, virt_addr, len, bus_addr) +- : dma_map_area_linear(r, virt_addr, len, bus_addr); ++ return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag); + } + + int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, + unsigned long len) + { +- return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len) +- : dma_unmap_area_linear(r, bus_addr, len); ++ return r->region_ops->unmap(r, bus_addr, len); + } + + /*============================================================================*/ +@@ -816,6 +1218,9 @@ void __init ps3_mm_init(void) + /* arrange to do this in ps3_mm_add_memory */ + ps3_mm_region_create(&map.r1, map.total - map.rm.size); + ++ /* correct map.total for the real total amount of memory we use */ ++ map.total = map.rm.size + map.r1.size; ++ + DBG(" <- %s:%d\n", __func__, __LINE__); + } + +--- a/arch/powerpc/platforms/ps3/platform.h ++++ b/arch/powerpc/platforms/ps3/platform.h +@@ -83,6 +83,7 @@ enum ps3_dev_type { + PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ + PS3_DEV_TYPE_SB_GPIO = 6, + PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ ++ PS3_DEV_TYPE_NOACCESS = 255, + }; + + int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, +@@ -217,4 +218,14 @@ int ps3_repository_read_num_spu_resource + int ps3_repository_read_spu_resource_id(unsigned int res_index, + enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); + ++/* Page table entries */ ++#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ ++#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ ++#define IOPTE_M 0x2000000000000000ul /* coherency required */ ++#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */ ++#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */ ++#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */ ++#define IOPTE_H 0x0000000000000800ul /* cache hint */ ++#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */ ++ + #endif +--- a/arch/powerpc/platforms/ps3/system-bus.c ++++ b/arch/powerpc/platforms/ps3/system-bus.c +@@ -30,22 +30,228 @@ + + #include "platform.h" + ++static struct device ps3_system_bus = { ++ .bus_id = "ps3_system", ++}; ++ ++/* FIXME: need device usage counters! */ ++struct { ++ struct mutex mutex; ++ int sb_11; // usb 0 ++ int sb_12; // usb 1 ++ int gpu; ++} static usage_hack; ++ ++static ps3_is_device(struct ps3_system_bus_device *dev, unsigned int bus_id, ++ unsigned int dev_id) ++{ ++ return dev->bus_id == bus_id && dev->dev_id == dev_id; ++} ++ ++static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev) ++{ ++ int result; ++ ++ BUG_ON(!dev->bus_id); ++ mutex_lock(&usage_hack.mutex); ++ ++ if(ps3_is_device(dev, 1, 1)) { ++ usage_hack.sb_11++; ++ if (usage_hack.sb_11 > 1) { ++ result = 0; ++ goto done; ++ } ++ } ++ ++ if(ps3_is_device(dev, 1, 2)) { ++ usage_hack.sb_12++; ++ if (usage_hack.sb_12 > 1) { ++ result = 0; ++ goto done; ++ } ++ } ++ ++ result = lv1_open_device(dev->bus_id, dev->dev_id, 0); ++ ++ if (result) { ++ pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ result = -EPERM; ++ } ++ ++done: ++ mutex_unlock(&usage_hack.mutex); ++ return result; ++} ++ ++static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev) ++{ ++ int result; ++ ++ BUG_ON(!dev->bus_id); ++ mutex_lock(&usage_hack.mutex); ++ ++ if(ps3_is_device(dev, 1, 1)) { ++ usage_hack.sb_11--; ++ if (usage_hack.sb_11) { ++ result = 0; ++ goto done; ++ } ++ } ++ ++ if(ps3_is_device(dev, 1, 2)) { ++ usage_hack.sb_12--; ++ if (usage_hack.sb_12) { ++ result = 0; ++ goto done; ++ } ++ } ++ ++ result = lv1_close_device(dev->bus_id, dev->dev_id); ++ BUG_ON(result); ++ ++done: ++ mutex_unlock(&usage_hack.mutex); ++ return result; ++} ++ ++static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev) ++{ ++ int result; ++ ++ mutex_lock(&usage_hack.mutex); ++ ++ usage_hack.gpu++; ++ if (usage_hack.gpu > 1) { ++ result = 0; ++ goto done; ++ } ++ ++ result = lv1_gpu_open(0); ++ ++ if (result) { ++ pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ result = -EPERM; ++ } ++ ++done: ++ mutex_unlock(&usage_hack.mutex); ++ return result; ++} ++ ++static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev) ++{ ++ int result; ++ ++ mutex_lock(&usage_hack.mutex); ++ ++ usage_hack.gpu--; ++ if (usage_hack.gpu) { ++ result = 0; ++ goto done; ++ } ++ ++ result = lv1_gpu_close(); ++ BUG_ON(result); ++ ++done: ++ mutex_unlock(&usage_hack.mutex); ++ return result; ++} ++ ++int ps3_open_hv_device(struct ps3_system_bus_device *dev) ++{ ++ BUG_ON(!dev); ++ pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id); ++ ++ switch(dev->match_id) { ++ case PS3_MATCH_ID_EHCI: ++ case PS3_MATCH_ID_OHCI: ++ case PS3_MATCH_ID_GELIC: ++ case PS3_MATCH_ID_STOR_DISK: ++ case PS3_MATCH_ID_STOR_ROM: ++ case PS3_MATCH_ID_STOR_FLASH: ++ return ps3_open_hv_device_sb(dev); ++ ++ case PS3_MATCH_ID_SOUND: ++ case PS3_MATCH_ID_GRAPHICS: ++ return ps3_open_hv_device_gpu(dev); ++ ++ case PS3_MATCH_ID_AV_SETTINGS: ++ case PS3_MATCH_ID_SYSTEM_MANAGER: ++ pr_debug("%s:%d: unsupported match_id: %u\n", __func__, ++ __LINE__, dev->match_id); ++ pr_debug("%s:%d: bus_id: %u\n", __func__, ++ __LINE__, dev->bus_id); ++ BUG(); ++ return -EINVAL; ++ ++ default: ++ break; ++ } ++ ++ pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__, ++ dev->match_id); ++ BUG(); ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(ps3_open_hv_device); ++ ++int ps3_close_hv_device(struct ps3_system_bus_device *dev) ++{ ++ BUG_ON(!dev); ++ pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id); ++ ++ switch(dev->match_id) { ++ case PS3_MATCH_ID_EHCI: ++ case PS3_MATCH_ID_OHCI: ++ case PS3_MATCH_ID_GELIC: ++ case PS3_MATCH_ID_STOR_DISK: ++ case PS3_MATCH_ID_STOR_ROM: ++ case PS3_MATCH_ID_STOR_FLASH: ++ return ps3_close_hv_device_sb(dev); ++ ++ case PS3_MATCH_ID_SOUND: ++ case PS3_MATCH_ID_GRAPHICS: ++ return ps3_close_hv_device_gpu(dev); ++ ++ case PS3_MATCH_ID_AV_SETTINGS: ++ case PS3_MATCH_ID_SYSTEM_MANAGER: ++ pr_debug("%s:%d: unsupported match_id: %u\n", __func__, ++ __LINE__, dev->match_id); ++ pr_debug("%s:%d: bus_id: %u\n", __func__, ++ __LINE__, dev->bus_id); ++ BUG(); ++ return -EINVAL; ++ ++ default: ++ break; ++ } ++ ++ pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__, ++ dev->match_id); ++ BUG(); ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(ps3_close_hv_device); ++ + #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) + static void _dump_mmio_region(const struct ps3_mmio_region* r, + const char* func, int line) + { +- pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, +- r->did.dev_id); ++ pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, ++ r->dev->dev_id); + pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); + pr_debug("%s:%d: len %lxh\n", func, line, r->len); + pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr); + } + +-int ps3_mmio_region_create(struct ps3_mmio_region *r) ++static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r) + { + int result; + +- result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id, ++ result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id, + r->bus_addr, r->len, r->page_size, &r->lpar_addr); + + if (result) { +@@ -57,13 +263,26 @@ int ps3_mmio_region_create(struct ps3_mm + dump_mmio_region(r); + return result; + } ++ ++static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r) ++{ ++ /* device specific; do nothing currently */ ++ return 0; ++} ++ ++int ps3_mmio_region_create(struct ps3_mmio_region *r) ++{ ++ return r->mmio_ops->create(r); ++} + EXPORT_SYMBOL_GPL(ps3_mmio_region_create); + +-int ps3_free_mmio_region(struct ps3_mmio_region *r) ++static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r) + { + int result; + +- result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, ++ dump_mmio_region(r); ++; ++ result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id, + r->lpar_addr); + + if (result) +@@ -73,14 +292,60 @@ int ps3_free_mmio_region(struct ps3_mmio + r->lpar_addr = 0; + return result; + } ++ ++static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r) ++{ ++ /* device specific; do nothing currently */ ++ return 0; ++} ++ ++ ++int ps3_free_mmio_region(struct ps3_mmio_region *r) ++{ ++ return r->mmio_ops->free(r); ++} ++ + EXPORT_SYMBOL_GPL(ps3_free_mmio_region); + ++static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = { ++ .create = ps3_sb_mmio_region_create, ++ .free = ps3_sb_free_mmio_region ++}; ++ ++static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = { ++ .create = ps3_ioc0_mmio_region_create, ++ .free = ps3_ioc0_free_mmio_region ++}; ++ ++int ps3_mmio_region_init(struct ps3_system_bus_device *dev, ++ struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len, ++ enum ps3_mmio_page_size page_size) ++{ ++ r->dev = dev; ++ r->bus_addr = bus_addr; ++ r->len = len; ++ r->page_size = page_size; ++ switch (dev->dev_type) { ++ case PS3_DEVICE_TYPE_SB: ++ r->mmio_ops = &ps3_mmio_sb_region_ops; ++ break; ++ case PS3_DEVICE_TYPE_IOC0: ++ r->mmio_ops = &ps3_mmio_ioc0_region_ops; ++ break; ++ default: ++ BUG(); ++ return -EINVAL; ++ } ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ps3_mmio_region_init); ++ + static int ps3_system_bus_match(struct device *_dev, + struct device_driver *_drv) + { + int result; +- struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv); +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + + result = dev->match_id == drv->match_id; + +@@ -92,72 +357,84 @@ static int ps3_system_bus_match(struct d + + static int ps3_system_bus_probe(struct device *_dev) + { +- int result; +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); +- struct ps3_system_bus_driver *drv = +- to_ps3_system_bus_driver(_dev->driver); ++ int result = 0; ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ struct ps3_system_bus_driver *drv; + +- result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0); +- +- if (result) { +- pr_debug("%s:%d: lv1_open_device failed (%d)\n", +- __func__, __LINE__, result); +- result = -EACCES; +- goto clean_none; +- } +- +- if (dev->d_region->did.bus_id) { +- result = ps3_dma_region_create(dev->d_region); +- +- if (result) { +- pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n", +- __func__, __LINE__, result); +- BUG_ON("check region type"); +- result = -EINVAL; +- goto clean_device; +- } +- } ++ BUG_ON(!dev); ++ pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); + ++ drv = ps3_system_bus_dev_to_system_bus_drv(dev); + BUG_ON(!drv); + +- if (drv->probe) ++ if(drv->probe) + result = drv->probe(dev); + else + pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, + dev->core.bus_id); + +- if (result) { +- pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__); +- goto clean_dma; +- } +- +- return result; +- +-clean_dma: +- ps3_dma_region_free(dev->d_region); +-clean_device: +- lv1_close_device(dev->did.bus_id, dev->did.dev_id); +-clean_none: ++ pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); + return result; + } + + static int ps3_system_bus_remove(struct device *_dev) + { +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); +- struct ps3_system_bus_driver *drv = +- to_ps3_system_bus_driver(_dev->driver); ++ int result = 0; ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ struct ps3_system_bus_driver *drv; ++ ++ BUG_ON(!dev); ++ pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); ++ ++ drv = ps3_system_bus_dev_to_system_bus_drv(dev); ++ BUG_ON(!drv); + + if (drv->remove) +- drv->remove(dev); ++ result = drv->remove(dev); + else +- pr_info("%s:%d: %s no remove method\n", __func__, __LINE__, +- dev->core.bus_id); ++ dev_dbg(&dev->core, "%s:%d %s: no remove method\n", ++ __func__, __LINE__, drv->core.name); + +- ps3_dma_region_free(dev->d_region); +- ps3_free_mmio_region(dev->m_region); +- lv1_close_device(dev->did.bus_id, dev->did.dev_id); ++ pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); ++ return result; ++} + +- return 0; ++static void ps3_system_bus_shutdown(struct device *_dev) ++{ ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ struct ps3_system_bus_driver *drv; ++ ++ BUG_ON(!dev); ++ ++ dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, ++ dev->match_id); ++ ++ if (!dev->core.driver) { ++ dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, ++ __LINE__); ++ return; ++ } ++ ++ drv = ps3_system_bus_dev_to_system_bus_drv(dev); ++ ++ BUG_ON(!drv); ++ ++ dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__, ++ dev->core.bus_id, drv->core.name); ++ ++ if (drv->shutdown) ++ drv->shutdown(dev); ++ else if (drv->remove) { ++ dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n", ++ __func__, __LINE__, drv->core.name); ++ drv->remove(dev); ++ } else { ++ dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n", ++ __func__, __LINE__, drv->core.name); ++ BUG(); ++ } ++ ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + } + + struct bus_type ps3_system_bus_type = { +@@ -165,17 +442,27 @@ struct bus_type ps3_system_bus_type = { + .match = ps3_system_bus_match, + .probe = ps3_system_bus_probe, + .remove = ps3_system_bus_remove, ++ .shutdown = ps3_system_bus_shutdown, + }; + +-int __init ps3_system_bus_init(void) ++static int __init ps3_system_bus_init(void) + { + int result; + + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return -ENODEV; + ++ printk(" -> %s:%d\n", __func__, __LINE__); ++ ++ mutex_init(&usage_hack.mutex); ++ ++ result = device_register(&ps3_system_bus); ++ BUG_ON(result); ++ + result = bus_register(&ps3_system_bus_type); + BUG_ON(result); ++ ++ printk(" <- %s:%d\n", __func__, __LINE__); + return result; + } + +@@ -185,16 +472,13 @@ core_initcall(ps3_system_bus_init); + * Returns the virtual address of the buffer and sets dma_handle + * to the dma address (mapping) of the first page. + */ +- + static void * ps3_alloc_coherent(struct device *_dev, size_t size, +- dma_addr_t *dma_handle, gfp_t flag) ++ dma_addr_t *dma_handle, gfp_t flag) + { + int result; +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + unsigned long virt_addr; + +- BUG_ON(!dev->d_region->bus_addr); +- + flag &= ~(__GFP_DMA | __GFP_HIGHMEM); + flag |= __GFP_ZERO; + +@@ -205,7 +489,8 @@ static void * ps3_alloc_coherent(struct + goto clean_none; + } + +- result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle); ++ result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle, ++ IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M); + + if (result) { + pr_debug("%s:%d: ps3_dma_map failed (%d)\n", +@@ -226,7 +511,7 @@ clean_none: + static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, + dma_addr_t dma_handle) + { +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + + ps3_dma_unmap(dev->d_region, dma_handle, size); + free_pages((unsigned long)vaddr, get_order(size)); +@@ -239,15 +524,16 @@ static void ps3_free_coherent(struct dev + * byte within the page as vaddr. + */ + +-static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size, ++static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, + enum dma_data_direction direction) + { +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + int result; + unsigned long bus_addr; + + result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, +- &bus_addr); ++ &bus_addr, ++ IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M); + + if (result) { + pr_debug("%s:%d: ps3_dma_map failed (%d)\n", +@@ -257,10 +543,43 @@ static dma_addr_t ps3_map_single(struct + return bus_addr; + } + ++static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, size_t size, ++ enum dma_data_direction direction) ++{ ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ int result; ++ unsigned long bus_addr; ++ u64 iopte_flag; ++ ++ iopte_flag = IOPTE_M; ++ switch (direction) { ++ case DMA_BIDIRECTIONAL: ++ iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW; ++ break; ++ case DMA_TO_DEVICE: ++ iopte_flag |= IOPTE_PP_R | IOPTE_SO_R; ++ break; ++ case DMA_FROM_DEVICE: ++ iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW; ++ break; ++ default: ++ /* not happned */ ++ BUG(); ++ }; ++ result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, ++ &bus_addr, iopte_flag); ++ ++ if (result) { ++ pr_debug("%s:%d: ps3_dma_map failed (%d)\n", ++ __func__, __LINE__, result); ++ } ++ return bus_addr; ++} ++ + static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction) + { +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + int result; + + result = ps3_dma_unmap(dev->d_region, dma_addr, size); +@@ -271,20 +590,20 @@ static void ps3_unmap_single(struct devi + } + } + +-static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, ++static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) + { + #if defined(CONFIG_PS3_DYNAMIC_DMA) + BUG_ON("do"); + return -EPERM; + #else +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + int i; + + for (i = 0; i < nents; i++, sg++) { + int result = ps3_dma_map(dev->d_region, + page_to_phys(sg->page) + sg->offset, sg->length, +- &sg->dma_address); ++ &sg->dma_address, 0); + + if (result) { + pr_debug("%s:%d: ps3_dma_map failed (%d)\n", +@@ -299,7 +618,14 @@ static int ps3_map_sg(struct device *_de + #endif + } + +-static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, ++static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction direction) ++{ ++ BUG(); ++ return 0; ++} ++ ++static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction) + { + #if defined(CONFIG_PS3_DYNAMIC_DMA) +@@ -307,18 +633,34 @@ static void ps3_unmap_sg(struct device * + #endif + } + ++static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg, ++ int nents, enum dma_data_direction direction) ++{ ++ BUG(); ++} ++ + static int ps3_dma_supported(struct device *_dev, u64 mask) + { + return mask >= DMA_32BIT_MASK; + } + +-static struct dma_mapping_ops ps3_dma_ops = { ++static struct dma_mapping_ops ps3_sb_dma_ops = { ++ .alloc_coherent = ps3_alloc_coherent, ++ .free_coherent = ps3_free_coherent, ++ .map_single = ps3_sb_map_single, ++ .unmap_single = ps3_unmap_single, ++ .map_sg = ps3_sb_map_sg, ++ .unmap_sg = ps3_sb_unmap_sg, ++ .dma_supported = ps3_dma_supported ++}; ++ ++static struct dma_mapping_ops ps3_ioc0_dma_ops = { + .alloc_coherent = ps3_alloc_coherent, + .free_coherent = ps3_free_coherent, +- .map_single = ps3_map_single, ++ .map_single = ps3_ioc0_map_single, + .unmap_single = ps3_unmap_single, +- .map_sg = ps3_map_sg, +- .unmap_sg = ps3_unmap_sg, ++ .map_sg = ps3_ioc0_map_sg, ++ .unmap_sg = ps3_ioc0_unmap_sg, + .dma_supported = ps3_dma_supported + }; + +@@ -328,7 +670,7 @@ static struct dma_mapping_ops ps3_dma_op + + static void ps3_system_bus_release_device(struct device *_dev) + { +- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); + kfree(dev); + } + +@@ -343,19 +685,38 @@ static void ps3_system_bus_release_devic + int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) + { + int result; +- static unsigned int dev_count = 1; ++ static unsigned int dev_ioc0_count; ++ static unsigned int dev_sb_count; ++ static unsigned int dev_vuart_count; + +- dev->core.parent = NULL; ++ if (!dev->core.parent) ++ dev->core.parent = &ps3_system_bus; + dev->core.bus = &ps3_system_bus_type; + dev->core.release = ps3_system_bus_release_device; + ++ switch (dev->dev_type) { ++ case PS3_DEVICE_TYPE_IOC0: ++ dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops; ++ snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), ++ "ioc0_%02x", ++dev_ioc0_count); ++ break; ++ case PS3_DEVICE_TYPE_SB: ++ dev->core.archdata.dma_ops = &ps3_sb_dma_ops; ++ snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), ++ "sb_%02x", ++dev_sb_count); ++ ++ break; ++ case PS3_DEVICE_TYPE_VUART: ++ snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), ++ "vuart_%02x", ++dev_vuart_count); ++ break; ++ default: ++ BUG(); ++ }; ++ + dev->core.archdata.of_node = NULL; +- dev->core.archdata.dma_ops = &ps3_dma_ops; + dev->core.archdata.numa_node = 0; + +- snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x", +- dev_count++); +- + pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); + + result = device_register(&dev->core); +@@ -368,9 +729,11 @@ int ps3_system_bus_driver_register(struc + { + int result; + ++ printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name); + drv->core.bus = &ps3_system_bus_type; + + result = driver_register(&drv->core); ++ printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name); + return result; + } + +@@ -378,7 +741,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_ + + void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) + { ++ printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name); + driver_unregister(&drv->core); ++ printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name); + } + + EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); +--- a/include/asm-powerpc/lv1call.h ++++ b/include/asm-powerpc/lv1call.h +@@ -238,6 +238,7 @@ LV1_CALL(destruct_virtual_address_space, + LV1_CALL(configure_irq_state_bitmap, 3, 0, 11 ) + LV1_CALL(connect_irq_plug_ext, 5, 0, 12 ) + LV1_CALL(release_memory, 1, 0, 13 ) ++LV1_CALL(put_iopte, 5, 0, 15 ) + LV1_CALL(disconnect_irq_plug_ext, 3, 0, 17 ) + LV1_CALL(construct_event_receive_port, 0, 1, 18 ) + LV1_CALL(destruct_event_receive_port, 1, 0, 19 ) +@@ -268,6 +269,8 @@ LV1_CALL(remove_repository_node, + LV1_CALL(read_htab_entries, 2, 5, 95 ) + LV1_CALL(set_dabr, 2, 0, 96 ) + LV1_CALL(get_total_execution_time, 2, 1, 103 ) ++LV1_CALL(allocate_io_segment, 3, 1, 116 ) ++LV1_CALL(release_io_segment, 2, 0, 117 ) + LV1_CALL(construct_io_irq_outlet, 1, 1, 120 ) + LV1_CALL(destruct_io_irq_outlet, 1, 0, 121 ) + LV1_CALL(map_htab, 1, 1, 122 ) +--- a/include/asm-powerpc/ps3.h ++++ b/include/asm-powerpc/ps3.h +@@ -49,18 +49,6 @@ enum ps3_param_av_multi_out { + + enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); + +-/** +- * struct ps3_device_id - HV bus device identifier from the system repository +- * @bus_id: HV bus id, {1..} (zero invalid) +- * @dev_id: HV device id, {0..} +- */ +- +-struct ps3_device_id { +- unsigned int bus_id; +- unsigned int dev_id; +-}; +- +- + /* dma routines */ + + enum ps3_dma_page_size { +@@ -75,6 +63,8 @@ enum ps3_dma_region_type { + PS3_DMA_INTERNAL = 2, + }; + ++struct ps3_dma_region_ops; ++ + /** + * struct ps3_dma_region - A per device dma state variables structure + * @did: The HV device id. +@@ -82,21 +72,43 @@ enum ps3_dma_region_type { + * @region_type: The HV region type. + * @bus_addr: The 'translated' bus address of the region. + * @len: The length in bytes of the region. ++ * @offset: The offset from the start of memory of the region. ++ * @ioid: The IOID of the device who owns this region + * @chunk_list: Opaque variable used by the ioc page manager. ++ * @region_ops: struct ps3_dma_region_ops - dma region operations + */ + + struct ps3_dma_region { +- struct ps3_device_id did; ++ struct ps3_system_bus_device *dev; ++ /* device variables */ ++ const struct ps3_dma_region_ops *region_ops; ++ unsigned char ioid; + enum ps3_dma_page_size page_size; + enum ps3_dma_region_type region_type; +- unsigned long bus_addr; + unsigned long len; ++ unsigned long offset; ++ //unsigned long iopte_flag; ++ ++ /* driver variables (set by ps3_dma_region_create) */ ++ unsigned long bus_addr; + struct { + spinlock_t lock; + struct list_head head; + } chunk_list; + }; + ++struct ps3_dma_region_ops { ++ int (*create)(struct ps3_dma_region *); ++ int (*free)(struct ps3_dma_region *); ++ int (*map)(struct ps3_dma_region *, ++ unsigned long virt_addr, ++ unsigned long len, ++ unsigned long * bus_addr, ++ u64 iopte_pp); ++ int (*unmap)(struct ps3_dma_region *, ++ unsigned long bus_addr, ++ unsigned long len); ++}; + /** + * struct ps3_dma_region_init - Helper to initialize structure variables + * +@@ -104,18 +116,16 @@ struct ps3_dma_region { + * ps3_system_bus_device_register. + */ + +-static inline void ps3_dma_region_init(struct ps3_dma_region *r, +- const struct ps3_device_id* did, enum ps3_dma_page_size page_size, +- enum ps3_dma_region_type region_type) +-{ +- r->did = *did; +- r->page_size = page_size; +- r->region_type = region_type; +-} ++struct ps3_system_bus_device; ++ ++int ps3_dma_region_init(struct ps3_system_bus_device *dev, ++ struct ps3_dma_region *r, enum ps3_dma_page_size page_size, ++ enum ps3_dma_region_type region_type, void *addr, unsigned long len); + int ps3_dma_region_create(struct ps3_dma_region *r); + int ps3_dma_region_free(struct ps3_dma_region *r); + int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, +- unsigned long len, unsigned long *bus_addr); ++ unsigned long len, unsigned long *bus_addr, ++ u64 iopte_pp); + int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, + unsigned long len); + +@@ -126,6 +136,7 @@ enum ps3_mmio_page_size { + PS3_MMIO_64K = 16U + }; + ++struct ps3_mmio_region_ops; + /** + * struct ps3_mmio_region - a per device mmio state variables structure + * +@@ -133,13 +144,18 @@ enum ps3_mmio_page_size { + */ + + struct ps3_mmio_region { +- struct ps3_device_id did; ++ struct ps3_system_bus_device *dev; ++ const struct ps3_mmio_region_ops * mmio_ops; + unsigned long bus_addr; + unsigned long len; + enum ps3_mmio_page_size page_size; + unsigned long lpar_addr; + }; + ++struct ps3_mmio_region_ops { ++ int (*create)(struct ps3_mmio_region *); ++ int (*free)(struct ps3_mmio_region *); ++}; + /** + * struct ps3_mmio_region_init - Helper to initialize structure variables + * +@@ -147,15 +163,9 @@ struct ps3_mmio_region { + * ps3_system_bus_device_register. + */ + +-static inline void ps3_mmio_region_init(struct ps3_mmio_region *r, +- const struct ps3_device_id* did, unsigned long bus_addr, +- unsigned long len, enum ps3_mmio_page_size page_size) +-{ +- r->did = *did; +- r->bus_addr = bus_addr; +- r->len = len; +- r->page_size = page_size; +-} ++int ps3_mmio_region_init(struct ps3_system_bus_device *dev, ++ struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len, ++ enum ps3_mmio_page_size page_size); + int ps3_mmio_region_create(struct ps3_mmio_region *r); + int ps3_free_mmio_region(struct ps3_mmio_region *r); + unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr); +@@ -188,11 +198,10 @@ int ps3_spe_irq_setup(enum ps3_cpu_bindi + unsigned int class, unsigned int *virq); + int ps3_spe_irq_destroy(unsigned int virq); + +-int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, +- const struct ps3_device_id *did, unsigned int interrupt_id, +- unsigned int *virq); +-int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, +- unsigned int interrupt_id, unsigned int virq); ++int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, ++ enum ps3_cpu_binding cpu, unsigned int *virq); ++int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, ++ unsigned int virq); + + /* lv1 result codes */ + +@@ -290,11 +299,33 @@ static inline const char* ps3_result(int + /* system bus routines */ + + enum ps3_match_id { +- PS3_MATCH_ID_EHCI = 1, +- PS3_MATCH_ID_OHCI, +- PS3_MATCH_ID_GELIC, +- PS3_MATCH_ID_AV_SETTINGS, +- PS3_MATCH_ID_SYSTEM_MANAGER, ++ PS3_MATCH_ID_EHCI = 1, ++ PS3_MATCH_ID_OHCI = 2, ++ PS3_MATCH_ID_GELIC = 3, ++ PS3_MATCH_ID_AV_SETTINGS = 4, ++ PS3_MATCH_ID_SYSTEM_MANAGER = 5, ++ PS3_MATCH_ID_STOR_DISK = 6, ++ PS3_MATCH_ID_STOR_ROM = 7, ++ PS3_MATCH_ID_STOR_FLASH = 8, ++ PS3_MATCH_ID_SOUND = 9, ++ PS3_MATCH_ID_GRAPHICS = 10, ++}; ++ ++#define PS3_MODULE_ALIAS_EHCI "ps3:1" ++#define PS3_MODULE_ALIAS_OHCI "ps3:2" ++#define PS3_MODULE_ALIAS_GELIC "ps3:3" ++#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4" ++#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5" ++#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6" ++#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7" ++#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" ++#define PS3_MODULE_ALIAS_SOUND "ps3:9" ++#define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" ++ ++enum ps3_system_bus_device_type { ++ PS3_DEVICE_TYPE_IOC0 = 1, ++ PS3_DEVICE_TYPE_SB, ++ PS3_DEVICE_TYPE_VUART, + }; + + /** +@@ -303,14 +334,23 @@ enum ps3_match_id { + + struct ps3_system_bus_device { + enum ps3_match_id match_id; +- struct ps3_device_id did; +- unsigned int interrupt_id; +-/* struct iommu_table *iommu_table; -- waiting for Ben's cleanups */ +- struct ps3_dma_region *d_region; +- struct ps3_mmio_region *m_region; ++ enum ps3_system_bus_device_type dev_type; ++ ++ unsigned int bus_id; /* SB */ ++ unsigned int dev_id; /* SB */ ++ unsigned int interrupt_id; /* SB */ ++ struct ps3_dma_region *d_region; /* SB, IOC0 */ ++ struct ps3_mmio_region *m_region; /* SB, IOC0*/ ++ unsigned int port_number; /* VUART */ ++ ++/* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ + struct device core; ++ void* driver_priv; /* private driver variables */ + }; + ++int ps3_open_hv_device(struct ps3_system_bus_device *dev); ++int ps3_close_hv_device(struct ps3_system_bus_device *dev); ++ + /** + * struct ps3_system_bus_driver - a driver for a device on the system bus + */ +@@ -320,6 +360,7 @@ struct ps3_system_bus_driver { + struct device_driver core; + int (*probe)(struct ps3_system_bus_device *); + int (*remove)(struct ps3_system_bus_device *); ++ int (*shutdown)(struct ps3_system_bus_device *); + /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */ + /* int (*resume)(struct ps3_system_bus_device *); */ + }; +@@ -327,16 +368,24 @@ struct ps3_system_bus_driver { + int ps3_system_bus_device_register(struct ps3_system_bus_device *dev); + int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv); + void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv); +-static inline struct ps3_system_bus_driver *to_ps3_system_bus_driver( ++ ++static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv( + struct device_driver *_drv) + { + return container_of(_drv, struct ps3_system_bus_driver, core); + } +-static inline struct ps3_system_bus_device *to_ps3_system_bus_device( ++static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev( + struct device *_dev) + { + return container_of(_dev, struct ps3_system_bus_device, core); + } ++static inline struct ps3_system_bus_driver * ++ ps3_system_bus_dev_to_system_bus_drv(struct ps3_system_bus_device *_dev) ++{ ++ BUG_ON(!_dev); ++ BUG_ON(!_dev->core.driver); ++ return ps3_drv_to_system_bus_drv(_dev->core.driver); ++} + + /** + * ps3_system_bus_set_drvdata - --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/33-ps3-zimage-zerocopy.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/33-ps3-zimage-zerocopy.patch @@ -0,0 +1,749 @@ +Subject: PS3: Bootwrapper support. + +zImage.ps3 is a gzip compressed rom image that contains a flat device tree, +an lv1 compatible entry point, a wrapper program, and an optional initrd. +zImage.ps3 is suitable for programming into the PS3 boot flash memory. +zImage.ps3 is also known as otheros.bld, and for convenience, a hard link +with the name otheros.bld is created when zImage.ps3 is built. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/Makefile | 26 ++- + arch/powerpc/boot/ps3-head.S | 75 +++++++++ + arch/powerpc/boot/ps3-hvcall.S | 297 +++++++++++++++++++++++++++++++++++++ + arch/powerpc/boot/ps3.c | 157 +++++++++++++++++++ + arch/powerpc/boot/wrapper | 40 ++++ + arch/powerpc/boot/zImage.ps3.lds.S | 50 ++++++ + arch/powerpc/platforms/ps3/mm.c | 2 + 7 files changed, 636 insertions(+), 11 deletions(-) + +--- a/arch/powerpc/boot/Makefile ++++ b/arch/powerpc/boot/Makefile +@@ -42,11 +42,14 @@ zliblinuxheader := zlib.h zconf.h zutil. + $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \ + $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) + ++src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3.c ps3-hvcall.S ++inc-plat-$(CONFIG_PPC_PS3) += lv1call.h ++ + src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ + ns16550.c serial.c simple_alloc.c div64.S util.S \ + gunzip_util.c elf_util.c $(zlib) devtree.c \ + 44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c +-src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \ ++src-plat := $(src-plat-y) of.c cuboot-83xx.c cuboot-85xx.c holly.c \ + cuboot-ebony.c treeboot-ebony.c prpmc2800.c + src-boot := $(src-wlib) $(src-plat) empty.c + +@@ -54,6 +57,7 @@ src-boot := $(addprefix $(obj)/, $(src-b + obj-boot := $(addsuffix .o, $(basename $(src-boot))) + obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) + obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) ++inc-plat := $(addprefix $(obj)/,$(inc-plat-y)) + + quiet_cmd_copy_zlib = COPY $@ + cmd_copy_zlib = sed "s@__attribute_used__@@;s@]*\).*@\"\1\"@" $< > $@ +@@ -73,14 +77,17 @@ $(addprefix $(obj)/,$(zlibheader)): $(ob + $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% + $(call cmd,copy_zliblinuxheader) + ++$(addprefix $(obj)/,$(inc-plat-y)): $(obj)/%: $(srctree)/include/asm-powerpc/% ++ $(call cmd,copy_zliblinuxheader) ++ + $(obj)/empty.c: + @touch $@ + +-$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S ++$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S + @cp $< $@ + + clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ +- empty.c zImage.coff.lds zImage.lds ++ empty.c zImage zImage.coff.lds zImage.ps3.lds zImage.lds + + quiet_cmd_bootcc = BOOTCC $@ + cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< +@@ -102,8 +109,8 @@ $(obj)/wrapper.a: $(obj-wlib) FORCE + hostprogs-y := addnote addRamDisk hack-coff mktree + + targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) +-extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ +- $(obj)/zImage.lds $(obj)/zImage.coff.lds ++extra-y := $(obj)/wrapper.a $(inc-plat) $(obj-plat) $(obj)/empty.o \ ++ $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds + + wrapper :=$(srctree)/$(src)/wrapper + wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ +@@ -188,11 +195,12 @@ $(obj)/zImage.%: vmlinux $(wrapperbits) + $(obj)/zImage.iseries: vmlinux + $(STRIP) -s -R .comment $< -o $@ + +-$(obj)/zImage.ps3: vmlinux +- $(STRIP) -s -R .comment $< -o $@ ++$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts ++ $(STRIP) -s -R .comment $< -o vmlinux.strip ++ $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,) + +-$(obj)/zImage.initrd.ps3: vmlinux +- @echo " WARNING zImage.initrd.ps3 not supported (yet)" ++$(obj)/zImage.initrd.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz ++ $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz) + + $(obj)/zImage.holly-elf: vmlinux $(wrapperbits) + $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,) +--- /dev/null ++++ b/arch/powerpc/boot/ps3-head.S +@@ -0,0 +1,75 @@ ++/* ++ * PS3 bootwrapper entry. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include "ppc_asm.h" ++ ++ .text ++ ++/* ++ * __system_reset_overlay - The PS3 first stage entry. ++ * ++ * The bootwraper build script copies the 0x100 bytes at symbol ++ * __system_reset_overlay to offset 0x100 of the rom image. ++ */ ++ ++ .globl __system_reset_overlay ++__system_reset_overlay: ++ ++ /* Switch to 32-bit mode. */ ++ ++ mfmsr r9 ++ clrldi r9,r9,1 ++ mtmsrd r9 ++ nop ++ ++ /* Get thread number in r3 and branch. */ ++ ++ mfspr r3, 0x88 ++ cntlzw. r3, r3 ++ li r4, 0 ++ li r5, 0 ++ beq 1f ++ ++ /* Secondary goes to __secondary_hold in kernel. */ ++ ++ li r4, 0x60 ++ mtctr r4 ++ bctr ++ ++ /* Primary goes to _zimage_start in wrapper. */ ++1: ++ lis r4, _zimage_start@ha ++ addi r4, r4, _zimage_start@l ++ mtctr r4 ++ bctr ++ ++/* ++ * __system_reset_kernel - Place holder for the kernel reset vector. ++ * ++ * The bootwrapper build script copies 0x100 bytes from offset 0x100 ++ * of the rom image to the symbol __system_reset_kernel. At runtime ++ * the bootwrapper program copies the 0x100 bytes at __system_reset_kernel ++ * to ram address 0x100. This symbol must occupy 0x100 bytes. ++ */ ++ ++ .globl __system_reset_kernel ++__system_reset_kernel: ++ ++ . = __system_reset_kernel + 0x100 +--- /dev/null ++++ b/arch/powerpc/boot/ps3-hvcall.S +@@ -0,0 +1,297 @@ ++/* ++ * PS3 hvcall interface. ++ * ++ * Copyright (C) 2006 Sony Computer Entertainment Inc. ++ * Copyright 2006 Sony Corp. ++ * Copyright 2003, 2004 (c) MontaVista Software, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include "ppc_asm.h" ++ ++/* ++ * wrapper lv1 ++ * 32-bit (h,l) 64-bit ++ * ++ * 1: r3,r4 <-> r3 ++ * 2: r5,r6 <-> r4 ++ * 3: r7,r8 <-> r5 ++ * 4: r9,r10 <-> r6 ++ * 5: 8(r1),12(r1) <-> r7 ++ * 6: 16(r1),20(r1) <-> r8 ++ * 7: 24(r1),28(r1) <-> r9 ++ * 8: 32(r1),36(r1) <-> r10 ++ * ++ */ ++ ++.macro global name ++ .section ".text" ++ .balign 4 ++ .globl \name ++\name: ++.endm ++ ++.macro no_support name ++ GLOBAL \name ++ b ps3_no_support ++.endm ++ ++.macro hvcall ++ .long 0x44000022 ++ extsw r3, r3 ++.endm ++ ++.macro save_lr offset=4 ++ mflr r0 ++ stw r0, \offset(r1) ++.endm ++ ++.macro load_lr offset=4 ++ lwz r0, \offset(r1) ++ mtlr r0 ++.endm ++ ++.macro load_64_reg target,high,low ++ sldi r11, \high, 32 ++ or \target, r11, \low ++.endm ++ ++.macro load_64_stack target,offset ++ ld \target, \offset(r1) ++.endm ++ ++.macro load_r3 ++ LOAD_64_REG r3,r3,r4 ++.endm ++ ++.macro load_r4 ++ LOAD_64_REG r4,r5,r6 ++.endm ++ ++.macro load_r5 ++ LOAD_64_REG r5,r7,r8 ++.endm ++ ++.macro load_r6 ++ LOAD_64_REG r6,r9,r10 ++.endm ++ ++.macro load_r7 ++ LOAD_64_STACK r7,8 ++.endm ++ ++.macro load_r8 ++ LOAD_64_STACK r8,16 ++.endm ++ ++.macro load_r9 ++ LOAD_64_STACK r9,24 ++.endm ++ ++.macro load_r10 ++ LOAD_64_STACK r10,32 ++.endm ++ ++.macro load_regs_5 ++ LOAD_R3 ++ LOAD_R4 ++ LOAD_R5 ++ LOAD_R6 ++ LOAD_R7 ++.endm ++ ++.macro load_regs_6 ++ LOAD_REGS_5 ++ LOAD_R8 ++.endm ++ ++.macro load_regs_8 ++ LOAD_REGS_6 ++ LOAD_R9 ++ LOAD_R10 ++.endm ++ ++.macro store_regs_0_1 ++ lwz r11, 8(r1) ++ std r4, 0(r11) ++.endm ++ ++.macro store_regs_5_2 ++ lwz r11, 16(r1) ++ std r4, 0(r11) ++ lwz r11, 24(r1) ++ std r5, 0(r11) ++.endm ++ ++.macro store_regs_6_1 ++ lwz r11, 24(r1) ++ std r4, 0(r11) ++.endm ++ ++#define LV1_N_IN_0_OUT(API_NAME, API_NUMBER) \ ++GLOBAL _##API_NAME; \ ++ SAVE_LR; \ ++ LOAD_REGS_8; \ ++ li r11, API_NUMBER; \ ++ HVCALL; \ ++ LOAD_LR; \ ++ blr ++ ++#define LV1_0_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_1_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_2_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_3_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_4_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_5_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_6_IN_0_OUT LV1_N_IN_0_OUT ++#define LV1_7_IN_0_OUT LV1_N_IN_0_OUT ++ ++.macro save_r5 ++ stw r5, 8(r1) ++.endm ++ ++.macro save_r6 ++ stw r6, 12(r1) ++.endm ++ ++.macro save_1 ++ SAVE_R5 ++ SAVE_R6 ++.endm ++ ++#define LV1_0_IN_1_OUT(API_NAME, API_NUMBER) \ ++GLOBAL _##API_NAME; \ ++ SAVE_LR; \ ++ stwu r1,-16(r1); \ ++ stw r3, 8(r1); \ ++ li r11, API_NUMBER; \ ++ HVCALL; \ ++ lwz r11, 8(r1); \ ++ std r4, 0(r11); \ ++ mr r4, r3; \ ++ li r3, 0; \ ++ addi r1,r1,16; \ ++ LOAD_LR; \ ++ blr ++ ++#define LV1_0_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_0_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_0_IN_7_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_4_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_5_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_1_IN_6_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT ++ ++#define LV1_1_IN_7_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_2_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_2_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_2_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_2_IN_4_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_2_IN_5_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_3_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_3_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_3_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_4_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_4_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_4_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_5_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_5_IN_2_OUT(API_NAME, API_NUMBER) \ ++GLOBAL _##API_NAME; \ ++ SAVE_LR; \ ++ LOAD_REGS_5; \ ++ li r11, API_NUMBER; \ ++ HVCALL; \ ++ STORE_REGS_5_2; \ ++ LOAD_LR; \ ++ blr ++ ++#define LV1_5_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_6_IN_1_OUT(API_NAME, API_NUMBER) \ ++GLOBAL _##API_NAME; \ ++ SAVE_LR; \ ++ LOAD_REGS_6; \ ++ li r11, API_NUMBER; \ ++ HVCALL; \ ++ STORE_REGS_6_1; \ ++ LOAD_LR; \ ++ blr ++ ++#define LV1_6_IN_2_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_6_IN_3_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_7_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_7_IN_6_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++#define LV1_8_IN_1_OUT(API_NAME, API_NUMBER) \ ++ NO_SUPPORT _##API_NAME ++ ++/* the lv1 underscored call definitions expand here */ ++ ++#define LV1_CALL(name, in, out, num) LV1_##in##_IN_##out##_OUT(lv1_##name, num) ++#include "lv1call.h" ++ +--- /dev/null ++++ b/arch/powerpc/boot/ps3.c +@@ -0,0 +1,157 @@ ++/* ++ * PS3 bootwrapper support. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include "types.h" ++#include "elf.h" ++#include "string.h" ++#include "stdio.h" ++#include "page.h" ++#include "ops.h" ++#include "lv1call.h" ++ ++#ifdef DEBUG ++#define DBG(fmt...) printf(fmt) ++#else ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} ++#endif ++ ++BSS_STACK(4096); ++ ++static void ps3_console_write(const char *buf, int len) ++{ ++} ++ ++static void ps3_exit(void) ++{ ++ printf("ps3_exit\n"); ++ lv1_panic(0); /* zero = no reboot */ ++ while(1); ++} ++ ++static int ps3_repository_read_rm_size(u64 *rm_size) ++{ ++ int result; ++ u64 lpar_id; ++ u64 ppe_id; ++ u64 v2; ++ ++ result = lv1_get_logical_partition_id(&lpar_id); ++ ++ if (result) ++ return -1; ++ ++ result = lv1_get_logical_ppe_id(&ppe_id); ++ ++ if (result) ++ return -1; ++ ++ /* ++ * n1: 0000000062690000 : ....bi.. ++ * n2: 7075000000000000 : pu...... ++ * n3: 0000000000000001 : ........ ++ * n4: 726d5f73697a6500 : rm_size. ++ */ ++ ++ result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL, ++ 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size, ++ &v2); ++ ++ printf("%s:%d: ppe_id %lu \n", __func__, __LINE__, ++ (unsigned long)ppe_id); ++ printf("%s:%d: lpar_id %lu \n", __func__, __LINE__, ++ (unsigned long)lpar_id); ++ printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size); ++ ++ return result; ++} ++ ++void ps3_copy_vectors(void) ++{ ++ extern char __system_reset_kernel[]; ++ ++ memcpy((void*)0x100, __system_reset_kernel, 0x100); ++ flush_cache((void*)0x100, 0x100); ++} ++ ++/* A buffer that may be edited by tools operating on a zImage binary so as to ++ * edit the command line passed to vmlinux (by setting /chosen/bootargs). ++ * The buffer is put in it's own section so that tools may locate it easier. ++ */ ++static char cmdline[COMMAND_LINE_SIZE] ++ __attribute__((__section__("__builtin_cmdline"))); ++ ++static void prep_cmdline(void *chosen) ++{ ++ if (cmdline[0] == '\0') ++ getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); ++ else ++ setprop_str(chosen, "bootargs", cmdline); ++ ++ printf("cmdline: '%s'\n", cmdline); ++} ++ ++void platform_init(void) ++{ ++ extern char _end[]; ++ extern char _dtb_start[]; ++ extern char _initrd_start[]; ++ extern char _initrd_end[]; ++ const u32 heapsize = 0x2000000 - (u32)_end; /* 32M */ ++ void *chosen; ++ unsigned long ft_addr; ++ u64 rm_size; ++ ++ console_ops.write = ps3_console_write; ++ platform_ops.exit = ps3_exit; ++ ++ printf("\n-- PS3 bootwrapper --\n"); ++ ++ ps3_copy_vectors(); ++ ++ simple_alloc_init(_end, heapsize, 32, 64); ++ ft_init(_dtb_start, 0, 4); ++ ++ chosen = finddevice("/chosen"); ++ ++ ps3_repository_read_rm_size(&rm_size); ++ dt_fixup_memory(0, rm_size); ++ ++ if (_initrd_end > _initrd_start) { ++ setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start)); ++ setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end)); ++ } ++ ++ prep_cmdline(chosen); ++ ++ ft_addr = dt_ops.finalize(); ++ ++ printf(" flat tree at 0x%lx\n\r", ft_addr); ++ ++ ((kernel_entry_t)0)(ft_addr, 0, NULL); ++} ++ ++void ps3_no_support(void) ++{ ++ printf("\n*** bootwrapper BUG: ps3_no_support() called!\n"); ++ ps3_exit(); ++} +--- a/arch/powerpc/boot/wrapper ++++ b/arch/powerpc/boot/wrapper +@@ -144,6 +144,15 @@ miboot|uboot) + cuboot*) + gzip= + ;; ++ps3) ++ platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" ++ lds=$object/zImage.ps3.lds ++ gzip= ++ ext=bin ++ objflags="-O binary" ++ ksection=.kernel:vmlinux.bin ++ isection=.kernel:initrd ++ ;; + esac + + vmz="$tmpdir/`basename \"$kernel\"`.$ext" +@@ -239,4 +248,35 @@ treeboot*) + fi + exit 0 + ;; ++ps3) ++ # The ps3's loader supports loading gzipped binary images from flash ++ # rom to addr zero. The loader enters the image at addr 0x100. A ++ # bootwrapper overlay is use to arrange for the kernel to be loaded ++ # to addr zero and to have a suitable bootwrapper entry at 0x100. ++ # To construct the rom image 0x100 bytes from offset 0x100 in the ++ # kernel is copied to the bootwrapper symbol __system_reset_kernel. ++ # The 0x100 bytes at the bootwrapper symbol __system_reset_overlay is ++ # then copied to offset 0x100. At runtime the bootwrapper program ++ # copies the 0x100 bytes at __system_reset_kernel to addr 0x100. ++ ++ system_reset_overlay=0x`${CROSS}nm "$ofile" | grep ' __system_reset_overlay$' | cut -d' ' -f1` ++ system_reset_overlay=`printf "%d" $system_reset_overlay` ++ system_reset_kernel=0x`${CROSS}nm "$ofile" | grep ' __system_reset_kernel$' | cut -d' ' -f1` ++ system_reset_kernel=`printf "%d" $system_reset_kernel` ++ overlay_dest="256" ++ overlay_size="256" ++ ++ rm -f "$object/otheros.bld" ++ ++ cp -a "$ofile" "$ofile.elf" ++ ${CROSS}objcopy -O binary "$ofile" "$ofile" ++ cp -a "$ofile" "$ofile.bin.org" ++ ++# dd if="$ofile" of="$ofile" conv=notrunc skip=$overlay_dest seek=$system_reset_kernel bs=1 count=$overlay_size ++ dd if="$ofile" of="$ofile" conv=notrunc skip=$system_reset_overlay seek=$overlay_dest bs=1 count=$overlay_size ++ ++ cp -a "$ofile" "$ofile.bin" ++ gzip --force -9 --stdout "$ofile.bin" > "$ofile" ++ ln "$ofile" "$object/otheros.bld" ++ ;; + esac +--- /dev/null ++++ b/arch/powerpc/boot/zImage.ps3.lds.S +@@ -0,0 +1,50 @@ ++OUTPUT_ARCH(powerpc:common) ++ENTRY(_zimage_start) ++EXTERN(_zimage_start) ++SECTIONS ++{ ++ _vmlinux_start = .; ++ .kernel:vmlinux.bin : { *(.kernel:vmlinux.bin) } ++ _vmlinux_end = .; ++ ++ . = ALIGN(8); ++ _dtb_start = .; ++ .kernel:dtb : { *(.kernel:dtb) } ++ _dtb_end = .; ++ ++ . = ALIGN(4096); ++ _initrd_start = .; ++ .kernel:initrd : { *(.kernel:initrd) } ++ _initrd_end = .; ++ ++ _start = .; ++ .text : ++ { ++ *(.text) ++ *(.fixup) ++ } ++ _etext = .; ++ . = ALIGN(4096); ++ .data : ++ { ++ *(.rodata*) ++ *(.data*) ++ *(.sdata*) ++ __got2_start = .; ++ *(.got2) ++ __got2_end = .; ++ } ++ ++ . = ALIGN(4096); ++ _edata = .; ++ ++ . = ALIGN(4096); ++ __bss_start = .; ++ .bss : ++ { ++ *(.sbss) ++ *(.bss) ++ } ++ . = ALIGN(4096); ++ _end = . ; ++} +--- a/arch/powerpc/platforms/ps3/mm.c ++++ b/arch/powerpc/platforms/ps3/mm.c +@@ -1211,8 +1211,6 @@ void __init ps3_mm_init(void) + BUG_ON(map.rm.base); + BUG_ON(!map.rm.size); + +- lmb_add(map.rm.base, map.rm.size); +- lmb_analyze(); + + /* arrange to do this in ps3_mm_add_memory */ + ps3_mm_region_create(&map.r1, map.total - map.rm.size); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/26-powerpc-correct-secondary_hold-comment.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/26-powerpc-correct-secondary_hold-comment.patch @@ -0,0 +1,24 @@ +Subject: Powerpc: Correct __secondary_hold comment + +Remove references to pSeries and OpenFirmware in the __secondary_hold +usage comment. __secondary_hold is a generic routine and can be used +by other platforms. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/kernel/head_64.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/head_64.S ++++ b/arch/powerpc/kernel/head_64.S +@@ -103,8 +103,8 @@ __secondary_hold_acknowledge: + + . = 0x60 + /* +- * The following code is used on pSeries to hold secondary processors +- * in a spin loop after they have been freed from OpenFirmware, but ++ * The following code is used to hold secondary processors ++ * in a spin loop after they have entered the kernel, but + * before the bulk of the kernel has been relocated. This code + * is relocated to physical address 0x60 before prom_init is run. + * All of it must fit below the first exception vector at 0x100. --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/12-ps3-system-bus-uevent.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/12-ps3-system-bus-uevent.patch @@ -0,0 +1,41 @@ +Subject: PS3: System-bus uevent +From: David Woodhouse + +To allow userspace to automatically load modules, we need to hook up +uevent for ps3_system_bus devices. I've used the form 'ps3:%d' with the +ps3_match_id, since that's what we use for matching drivers. + +Signed-off-by: David Woodhouse +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/system-bus.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/arch/powerpc/platforms/ps3/system-bus.c ++++ b/arch/powerpc/platforms/ps3/system-bus.c +@@ -433,9 +433,25 @@ static void ps3_system_bus_shutdown(stru + dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + } + ++static int ps3_system_bus_uevent(struct device *_dev, char **envp, ++ int num_envp, char *buffer, int buffer_size) ++{ ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ int i=0, length = 0; ++ ++ if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, ++ &length, "MODALIAS=ps3:%d", ++ dev->match_id)) ++ return -ENOMEM; ++ ++ envp[i] = NULL; ++ return 0; ++} ++ + struct bus_type ps3_system_bus_type = { + .name = "ps3_system_bus", + .match = ps3_system_bus_match, ++ .uevent = ps3_system_bus_uevent, + .probe = ps3_system_bus_probe, + .remove = ps3_system_bus_remove, + .shutdown = ps3_system_bus_shutdown, --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/03-ps3-compare-firmware-version.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/03-ps3-compare-firmware-version.patch @@ -0,0 +1,80 @@ +Subject: PS3: Compare firmware version +From: Masakazu Mokuno + +Add a utility routine ps3_compare_firmware_version() to compare system +firmware versions. Uses the existing ps3_get_firmware_version() routine. + +Signed-off-by: Masakazu Mokuno +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/setup.c | 32 ++++++++++++++++++++------------ + include/asm-powerpc/ps3.h | 3 ++- + 2 files changed, 22 insertions(+), 13 deletions(-) + +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -46,18 +46,26 @@ + static void smp_send_stop(void) {} + #endif + +-int ps3_get_firmware_version(union ps3_firmware_version *v) ++static union ps3_firmware_version ps3_firmware_version; ++ ++void ps3_get_firmware_version(union ps3_firmware_version *v) + { +- int result = lv1_get_version_info(&v->raw); ++ *v = ps3_firmware_version; ++} ++EXPORT_SYMBOL_GPL(ps3_get_firmware_version); + +- if (result) { +- v->raw = 0; +- return -1; +- } ++int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev) ++{ ++ union ps3_firmware_version x; ++ ++ x.pad = 0; ++ x.major = major; ++ x.minor = minor; ++ x.rev = rev; + +- return result; ++ return (ps3_firmware_version.raw - x.raw); + } +-EXPORT_SYMBOL_GPL(ps3_get_firmware_version); ++EXPORT_SYMBOL_GPL(ps3_compare_firmware_version); + + static void ps3_power_save(void) + { +@@ -146,13 +154,13 @@ static int ps3_set_dabr(u64 dabr) + + static void __init ps3_setup_arch(void) + { +- union ps3_firmware_version v; + + DBG(" -> %s:%d\n", __func__, __LINE__); + +- ps3_get_firmware_version(&v); +- printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", v.major, v.minor, +- v.rev); ++ lv1_get_version_info(&ps3_firmware_version.raw); ++ printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", ++ ps3_firmware_version.major, ps3_firmware_version.minor, ++ ps3_firmware_version.rev); + + ps3_spu_set_platform(); + ps3_map_htab(); +--- a/include/asm-powerpc/ps3.h ++++ b/include/asm-powerpc/ps3.h +@@ -35,7 +35,8 @@ union ps3_firmware_version { + }; + }; + +-int ps3_get_firmware_version(union ps3_firmware_version *v); ++void ps3_get_firmware_version(union ps3_firmware_version *v); ++int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev); + + /* 'Other OS' area */ + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/28-powerpc-zimage-u64-printf.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/28-powerpc-zimage-u64-printf.patch @@ -0,0 +1,36 @@ +Subject: Powerpc: Add u64 printf to bootwrapper + +Add support for the 'll' (long long) printf qualifier in the powerpc zImage +bootwrapper. This is useful for bootwrapper debugging on 64 bit platforms. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/stdio.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/boot/stdio.c ++++ b/arch/powerpc/boot/stdio.c +@@ -190,7 +190,11 @@ int vsprintf(char *buf, const char *fmt, + + /* get the conversion qualifier */ + qualifier = -1; +- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { ++ if (*fmt == 'l' && *(fmt + 1) =='l') { ++ qualifier = 'q'; ++ fmt += 2; ++ } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ++ || *fmt =='Z') { + qualifier = *fmt; + ++fmt; + } +@@ -281,6 +285,10 @@ int vsprintf(char *buf, const char *fmt, + num = va_arg(args, unsigned long); + if (flags & SIGN) + num = (signed long) num; ++ } else if (qualifier == 'q') { ++ num = va_arg(args, unsigned long long); ++ if (flags & SIGN) ++ num = (signed long long) num; + } else if (qualifier == 'Z') { + num = va_arg(args, size_t); + } else if (qualifier == 'h') { --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/19-ps3-system-bus-rework-ps3av.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/19-ps3-system-bus-rework-ps3av.patch @@ -0,0 +1,918 @@ +Subject: PS3: Rework AV settings driver + +Make the PS3 ps3av driver a loadable module. + - Replace static data with malloc'ed. + o Allocate struct ps3av dynamically, as it contains data used as vuart + receive/transmit buffers + o Move static recv_buf from ps3av_do_pkt() to struct ps3av + - Move ps3av_vuart_{read,write}() from drivers/ps3/ps3av_cmd.c to + drivers/ps3/ps3av.c and make them static as they're used in that file only. + - Make device a PS3 system-bus device. + - Update copyright formatting. + - Make two new routines ps3av_register_flip_ctl() and ps3av_flip_ctl() to + support late binding of the frame buffer flip control routine. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + drivers/ps3/Makefile | 3 + drivers/ps3/ps3av.c | 371 +++++++++++++++++++++++--------------------- + drivers/ps3/ps3av_cmd.c | 35 ---- + include/asm-powerpc/ps3av.h | 36 ++-- + 4 files changed, 220 insertions(+), 225 deletions(-) + +--- a/drivers/ps3/Makefile ++++ b/drivers/ps3/Makefile +@@ -1,4 +1,5 @@ + obj-$(CONFIG_PS3_VUART) += vuart.o +-obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o ++obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o ++ps3av_mod-objs += ps3av.o ps3av_cmd.o + obj-$(CONFIG_PPC_PS3) += sys-manager-core.o + obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o +--- a/drivers/ps3/ps3av.c ++++ b/drivers/ps3/ps3av.c +@@ -1,32 +1,30 @@ + /* +- * Copyright (C) 2006 Sony Computer Entertainment Inc. +- * Copyright 2006, 2007 Sony Corporation ++ * PS3 AV backend support. + * +- * AV backend support for PS3 ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published +- * by the Free Software Foundation; version 2 of the License. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. + * +- * 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. ++ * 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., +- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +- ++#define DEBUG ++#include + #include + #include + #include +-#include +-#include + #include + + #include +-#include + #include + #include + +@@ -39,13 +37,12 @@ static int timeout = 5000; /* in msec ( + module_param(timeout, int, 0644); + + static struct ps3av { +- int available; + struct mutex mutex; + struct work_struct work; + struct completion done; + struct workqueue_struct *wq; + int open_count; +- struct ps3_vuart_port_device *dev; ++ struct ps3_system_bus_device *dev; + + int region; + struct ps3av_pkt_av_get_hw_conf av_hw_conf; +@@ -55,11 +52,13 @@ static struct ps3av { + u32 audio_port; + int ps3av_mode; + int ps3av_mode_old; +-} ps3av; +- +-static struct ps3_vuart_port_device ps3av_dev = { +- .match_id = PS3_MATCH_ID_AV_SETTINGS +-}; ++ union { ++ struct ps3av_reply_hdr reply_hdr; ++ u8 raw[PS3AV_BUF_SIZE]; ++ } recv_buf; ++ void (*flip_ctl)(int on, void *data); ++ void *flip_data; ++} *ps3av; + + /* color space */ + #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 +@@ -169,7 +168,7 @@ static int ps3av_parse_event_packet(cons + if (hdr->cid & PS3AV_EVENT_CMD_MASK) { + table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); + if (table) +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "recv event packet cid:%08x port:0x%x size:%d\n", + hdr->cid, ps3av_event_get_port_id(hdr->cid), + hdr->size); +@@ -182,6 +181,41 @@ static int ps3av_parse_event_packet(cons + return 0; + } + ++ ++#define POLLING_INTERVAL 25 /* in msec */ ++ ++static int ps3av_vuart_write(struct ps3_system_bus_device *dev, ++ const void *buf, unsigned long size) ++{ ++ int error; ++ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); ++ error = ps3_vuart_write(dev, buf, size); ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); ++ return error ? error : size; ++} ++ ++static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf, ++ unsigned long size, int timeout) ++{ ++ int error; ++ int loopcnt = 0; ++ ++ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); ++ timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL; ++ while (loopcnt++ <= timeout) { ++ error = ps3_vuart_read(dev, buf, size); ++ if (!error) ++ return size; ++ if (error != -EAGAIN) { ++ printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", ++ __func__, error); ++ return error; ++ } ++ msleep(POLLING_INTERVAL); ++ } ++ return -EWOULDBLOCK; ++} ++ + static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, + struct ps3av_reply_hdr *recv_buf, int write_len, + int read_len) +@@ -190,13 +224,13 @@ static int ps3av_send_cmd_pkt(const stru + u32 cmd; + int event; + +- if (!ps3av.available) ++ if (!ps3av) + return -ENODEV; + + /* send pkt */ +- res = ps3av_vuart_write(ps3av.dev, send_buf, write_len); ++ res = ps3av_vuart_write(ps3av->dev, send_buf, write_len); + if (res < 0) { +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "%s: ps3av_vuart_write() failed (result=%d)\n", + __func__, res); + return res; +@@ -206,20 +240,20 @@ static int ps3av_send_cmd_pkt(const stru + cmd = send_buf->cid; + do { + /* read header */ +- res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE, ++ res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE, + timeout); + if (res != PS3AV_HDR_SIZE) { +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "%s: ps3av_vuart_read() failed (result=%d)\n", + __func__, res); + return res; + } + + /* read body */ +- res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid, ++ res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid, + recv_buf->size, timeout); + if (res < 0) { +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "%s: ps3av_vuart_read() failed (result=%d)\n", + __func__, res); + return res; +@@ -230,7 +264,7 @@ static int ps3av_send_cmd_pkt(const stru + } while (event); + + if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { +- dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", ++ dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n", + __func__, recv_buf->cid); + return -EINVAL; + } +@@ -245,7 +279,7 @@ static int ps3av_process_reply_packet(st + int return_len; + + if (recv_buf->version != PS3AV_VERSION) { +- dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n", ++ dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n", + recv_buf->version); + return -EFAULT; + } +@@ -267,16 +301,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, + struct ps3av_send_hdr *buf) + { + int res = 0; +- static union { +- struct ps3av_reply_hdr reply_hdr; +- u8 raw[PS3AV_BUF_SIZE]; +- } recv_buf; +- + u32 *table; + +- BUG_ON(!ps3av.available); ++ BUG_ON(!ps3av); + +- mutex_lock(&ps3av.mutex); ++ mutex_lock(&ps3av->mutex); + + table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); + BUG_ON(!table); +@@ -288,7 +317,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, + ps3av_set_hdr(cid, send_len, buf); + + /* send packet via vuart */ +- res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len, ++ res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len, + usr_buf_size); + if (res < 0) { + printk(KERN_ERR +@@ -298,7 +327,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, + } + + /* process reply packet */ +- res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr, ++ res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr, + usr_buf_size); + if (res < 0) { + printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", +@@ -306,11 +335,11 @@ int ps3av_do_pkt(u32 cid, u16 send_len, + goto err; + } + +- mutex_unlock(&ps3av.mutex); ++ mutex_unlock(&ps3av->mutex); + return 0; + + err: +- mutex_unlock(&ps3av.mutex); ++ mutex_unlock(&ps3av->mutex); + printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); + return res; + } +@@ -319,11 +348,11 @@ static int ps3av_set_av_video_mute(u32 m + { + int i, num_of_av_port, res; + +- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + +- ps3av.av_hw_conf.num_of_avmulti; ++ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + ++ ps3av->av_hw_conf.num_of_avmulti; + /* video mute on */ + for (i = 0; i < num_of_av_port; i++) { +- res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute); ++ res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute); + if (res < 0) + return -1; + } +@@ -335,13 +364,13 @@ static int ps3av_set_video_disable_sig(v + { + int i, num_of_hdmi_port, num_of_av_port, res; + +- num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi; +- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + +- ps3av.av_hw_conf.num_of_avmulti; ++ num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi; ++ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + ++ ps3av->av_hw_conf.num_of_avmulti; + + /* tv mute */ + for (i = 0; i < num_of_hdmi_port; i++) { +- res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], ++ res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], + PS3AV_CMD_MUTE_ON); + if (res < 0) + return -1; +@@ -350,11 +379,11 @@ static int ps3av_set_video_disable_sig(v + + /* video mute on */ + for (i = 0; i < num_of_av_port; i++) { +- res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]); ++ res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]); + if (res < 0) + return -1; + if (i < num_of_hdmi_port) { +- res = ps3av_cmd_av_tv_mute(ps3av.av_port[i], ++ res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], + PS3AV_CMD_MUTE_OFF); + if (res < 0) + return -1; +@@ -369,17 +398,17 @@ static int ps3av_set_audio_mute(u32 mute + { + int i, num_of_av_port, num_of_opt_port, res; + +- num_of_av_port = ps3av.av_hw_conf.num_of_hdmi + +- ps3av.av_hw_conf.num_of_avmulti; +- num_of_opt_port = ps3av.av_hw_conf.num_of_spdif; ++ num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + ++ ps3av->av_hw_conf.num_of_avmulti; ++ num_of_opt_port = ps3av->av_hw_conf.num_of_spdif; + + for (i = 0; i < num_of_av_port; i++) { +- res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute); ++ res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute); + if (res < 0) + return -1; + } + for (i = 0; i < num_of_opt_port; i++) { +- res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute); ++ res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute); + if (res < 0) + return -1; + } +@@ -394,40 +423,40 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, + struct ps3av_pkt_audio_mode audio_mode; + u32 len = 0; + +- num_of_audio = ps3av.av_hw_conf.num_of_hdmi + +- ps3av.av_hw_conf.num_of_avmulti + +- ps3av.av_hw_conf.num_of_spdif; ++ num_of_audio = ps3av->av_hw_conf.num_of_hdmi + ++ ps3av->av_hw_conf.num_of_avmulti + ++ ps3av->av_hw_conf.num_of_spdif; + + avb_param.num_of_video_pkt = 0; + avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ + avb_param.num_of_av_video_pkt = 0; +- avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi; ++ avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi; + +- vid = video_mode_table[ps3av.ps3av_mode].vid; ++ vid = video_mode_table[ps3av->ps3av_mode].vid; + + /* audio mute */ + ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); + + /* audio inactive */ +- res = ps3av_cmd_audio_active(0, ps3av.audio_port); ++ res = ps3av_cmd_audio_active(0, ps3av->audio_port); + if (res < 0) +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "ps3av_cmd_audio_active OFF failed\n"); + + /* audio_pkt */ + for (i = 0; i < num_of_audio; i++) { +- ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs, +- word_bits, format, source); +- if (i < ps3av.av_hw_conf.num_of_hdmi) { ++ ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch, ++ fs, word_bits, format, source); ++ if (i < ps3av->av_hw_conf.num_of_hdmi) { + /* hdmi only */ + len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], +- ps3av.av_port[i], ++ ps3av->av_port[i], + &audio_mode, vid); + } + /* audio_mode pkt should be sent separately */ + res = ps3av_cmd_audio_mode(&audio_mode); + if (res < 0) +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "ps3av_cmd_audio_mode failed, port:%x\n", i); + } + +@@ -435,15 +464,15 @@ int ps3av_set_audio_mode(u32 ch, u32 fs, + len += offsetof(struct ps3av_pkt_avb_param, buf); + res = ps3av_cmd_avb_param(&avb_param, len); + if (res < 0) +- dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); ++ dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); + + /* audio mute */ + ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); + + /* audio active */ +- res = ps3av_cmd_audio_active(1, ps3av.audio_port); ++ res = ps3av_cmd_audio_active(1, ps3av->audio_port); + if (res < 0) +- dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n"); ++ dev_dbg(&ps3av->dev->core, "ps3av_cmd_audio_active ON failed\n"); + + return 0; + } +@@ -456,7 +485,7 @@ static int ps3av_set_videomode(void) + ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); + + /* wake up ps3avd to do the actual video mode setting */ +- queue_work(ps3av.wq, &ps3av.work); ++ queue_work(ps3av->wq, &ps3av->work); + + return 0; + } +@@ -473,8 +502,8 @@ static void ps3av_set_videomode_cont(u32 + + avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ + avb_param.num_of_audio_pkt = 0; +- avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi + +- ps3av.av_hw_conf.num_of_avmulti; ++ avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi + ++ ps3av->av_hw_conf.num_of_avmulti; + avb_param.num_of_av_audio_pkt = 0; + + /* video signal off */ +@@ -484,21 +513,21 @@ static void ps3av_set_videomode_cont(u32 + if (id & PS3AV_MODE_HDCP_OFF) { + res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); + if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) +- dev_dbg(&ps3av_dev.core, "Not supported\n"); ++ dev_dbg(&ps3av->dev->core, "Not supported\n"); + else if (res) +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "ps3av_cmd_av_hdmi_mode failed\n"); + } else if (old_id & PS3AV_MODE_HDCP_OFF) { + res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); + if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) +- dev_dbg(&ps3av_dev.core, ++ dev_dbg(&ps3av->dev->core, + "ps3av_cmd_av_hdmi_mode failed\n"); + } + + /* video_pkt */ + for (i = 0; i < avb_param.num_of_video_pkt; i++) + len += ps3av_cmd_set_video_mode(&avb_param.buf[len], +- ps3av.head[i], video_mode->vid, ++ ps3av->head[i], video_mode->vid, + video_mode->fmt, id); + /* av_video_pkt */ + for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { +@@ -507,12 +536,12 @@ static void ps3av_set_videomode_cont(u32 + else + av_video_cs = video_mode->cs; + #ifndef PS3AV_HDMI_YUV +- if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || +- ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) ++ if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || ++ ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) + av_video_cs = RGB8; /* use RGB for HDMI */ + #endif + len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], +- ps3av.av_port[i], ++ ps3av->av_port[i], + video_mode->vid, av_video_cs, + video_mode->aspect, id); + } +@@ -524,7 +553,7 @@ static void ps3av_set_videomode_cont(u32 + "%s: Command failed. Please try your request again. \n", + __func__); + else if (res) +- dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); ++ dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); + + msleep(1500); + /* av video mute */ +@@ -533,8 +562,8 @@ static void ps3av_set_videomode_cont(u32 + + static void ps3avd(struct work_struct *work) + { +- ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old); +- complete(&ps3av.done); ++ ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old); ++ complete(&ps3av->done); + } + + static int ps3av_vid2table_id(int vid) +@@ -601,7 +630,7 @@ static int ps3av_hdmi_get_vid(struct ps3 + return vid; + } + +- if (ps3av.region & PS3AV_REGION_60) ++ if (ps3av->region & PS3AV_REGION_60) + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; + else + vid = PS3AV_DEFAULT_HDMI_VID_REG_50; +@@ -643,16 +672,16 @@ static int ps3av_auto_videomode(struct p + vid = PS3AV_DEFAULT_DVI_VID; + } else if (vid == -1) { + /* no HDMI interface or HDMI is off */ +- if (ps3av.region & PS3AV_REGION_60) ++ if (ps3av->region & PS3AV_REGION_60) + vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; + else + vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; +- if (ps3av.region & PS3AV_REGION_RGB) ++ if (ps3av->region & PS3AV_REGION_RGB) + rgb = PS3AV_MODE_RGB; + } else if (boot) { + /* HDMI: using DEFAULT HDMI_VID while booting up */ + info = &monitor_info.info; +- if (ps3av.region & PS3AV_REGION_60) { ++ if (ps3av->region & PS3AV_REGION_60) { + if (info->res_60.res_bits & PS3AV_RESBIT_720x480P) + vid = PS3AV_DEFAULT_HDMI_VID_REG_60; + else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P) +@@ -715,14 +744,14 @@ int ps3av_set_video_mode(u32 id, int boo + + size = ARRAY_SIZE(video_mode_table); + if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { +- dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id); ++ dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id); + return -EINVAL; + } + + /* auto mode */ + option = id & ~PS3AV_MODE_MASK; + if ((id & PS3AV_MODE_MASK) == 0) { +- id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); ++ id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot); + if (id < 1) { + printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); + return -EINVAL; +@@ -731,11 +760,11 @@ int ps3av_set_video_mode(u32 id, int boo + } + + /* set videomode */ +- wait_for_completion(&ps3av.done); +- ps3av.ps3av_mode_old = ps3av.ps3av_mode; +- ps3av.ps3av_mode = id; ++ wait_for_completion(&ps3av->done); ++ ps3av->ps3av_mode_old = ps3av->ps3av_mode; ++ ps3av->ps3av_mode = id; + if (ps3av_set_videomode()) +- ps3av.ps3av_mode = ps3av.ps3av_mode_old; ++ ps3av->ps3av_mode = ps3av->ps3av_mode_old; + + return 0; + } +@@ -744,7 +773,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_video_mode); + + int ps3av_get_auto_mode(int boot) + { +- return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); ++ return ps3av_auto_videomode(&ps3av->av_hw_conf, boot); + } + + EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); +@@ -772,7 +801,7 @@ EXPORT_SYMBOL_GPL(ps3av_set_mode); + + int ps3av_get_mode(void) + { +- return ps3av.ps3av_mode; ++ return ps3av ? ps3av->ps3av_mode : 0; + } + + EXPORT_SYMBOL_GPL(ps3av_get_mode); +@@ -842,82 +871,65 @@ int ps3av_audio_mute(int mute) + + EXPORT_SYMBOL_GPL(ps3av_audio_mute); + +-int ps3av_dev_open(void) ++void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), ++ void *flip_data) + { +- int status = 0; +- +- mutex_lock(&ps3av.mutex); +- if (!ps3av.open_count++) { +- status = lv1_gpu_open(0); +- if (status) { +- printk(KERN_ERR "%s: lv1_gpu_open failed %d\n", +- __func__, status); +- ps3av.open_count--; +- } +- } +- mutex_unlock(&ps3av.mutex); +- +- return status; ++ mutex_lock(&ps3av->mutex); ++ ps3av->flip_ctl = flip_ctl; ++ ps3av->flip_data = flip_data; ++ mutex_unlock(&ps3av->mutex); + } ++EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl); + +-EXPORT_SYMBOL_GPL(ps3av_dev_open); +- +-int ps3av_dev_close(void) ++void ps3av_flip_ctl(int on) + { +- int status = 0; +- +- mutex_lock(&ps3av.mutex); +- if (ps3av.open_count <= 0) { +- printk(KERN_ERR "%s: GPU already closed\n", __func__); +- status = -1; +- } else if (!--ps3av.open_count) { +- status = lv1_gpu_close(); +- if (status) +- printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n", +- __func__, status); +- } +- mutex_unlock(&ps3av.mutex); +- +- return status; ++ mutex_lock(&ps3av->mutex); ++ if (ps3av->flip_ctl) ++ ps3av->flip_ctl(on, ps3av->flip_data); ++ mutex_unlock(&ps3av->mutex); + } + +-EXPORT_SYMBOL_GPL(ps3av_dev_close); +- +-static int ps3av_probe(struct ps3_vuart_port_device *dev) ++static int ps3av_probe(struct ps3_system_bus_device *dev) + { + int res; + u32 id; + +- dev_dbg(&ps3av_dev.core, "init ...\n"); +- dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout); ++ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); ++ dev_dbg(&dev->core, " timeout=%d\n", timeout); + +- memset(&ps3av, 0, sizeof(ps3av)); ++ if (ps3av) { ++ dev_err(&dev->core, "Only one ps3av device is supported\n"); ++ return -EBUSY; ++ } + +- mutex_init(&ps3av.mutex); +- ps3av.ps3av_mode = 0; +- ps3av.dev = dev; +- +- INIT_WORK(&ps3av.work, ps3avd); +- init_completion(&ps3av.done); +- complete(&ps3av.done); +- ps3av.wq = create_singlethread_workqueue("ps3avd"); +- if (!ps3av.wq) ++ ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL); ++ if (!ps3av) + return -ENOMEM; + +- ps3av.available = 1; ++ mutex_init(&ps3av->mutex); ++ ps3av->ps3av_mode = 0; ++ ps3av->dev = dev; ++ ++ INIT_WORK(&ps3av->work, ps3avd); ++ init_completion(&ps3av->done); ++ complete(&ps3av->done); ++ ps3av->wq = create_singlethread_workqueue("ps3avd"); ++ if (!ps3av->wq) ++ goto fail; ++ + switch (ps3_os_area_get_av_multi_out()) { + case PS3_PARAM_AV_MULTI_OUT_NTSC: +- ps3av.region = PS3AV_REGION_60; ++ ps3av->region = PS3AV_REGION_60; + break; + case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: + case PS3_PARAM_AV_MULTI_OUT_SECAM: +- ps3av.region = PS3AV_REGION_50; ++ ps3av->region = PS3AV_REGION_50; + break; + case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: +- ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB; ++ ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB; + break; + default: +- ps3av.region = PS3AV_REGION_60; ++ ps3av->region = PS3AV_REGION_60; + break; + } + +@@ -927,38 +939,48 @@ static int ps3av_probe(struct ps3_vuart_ + printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, + res); + +- ps3av_get_hw_conf(&ps3av); +- id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1); +- mutex_lock(&ps3av.mutex); +- ps3av.ps3av_mode = id; +- mutex_unlock(&ps3av.mutex); ++ ps3av_get_hw_conf(ps3av); ++ id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1); ++ mutex_lock(&ps3av->mutex); ++ ps3av->ps3av_mode = id; ++ mutex_unlock(&ps3av->mutex); + +- dev_dbg(&ps3av_dev.core, "init...done\n"); ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + + return 0; ++ ++fail: ++ kfree(ps3av); ++ ps3av = NULL; ++ return -ENOMEM; + } + +-static int ps3av_remove(struct ps3_vuart_port_device *dev) ++static int ps3av_remove(struct ps3_system_bus_device *dev) + { +- if (ps3av.available) { ++ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); ++ if (ps3av) { + ps3av_cmd_fin(); +- if (ps3av.wq) +- destroy_workqueue(ps3av.wq); +- ps3av.available = 0; ++ if (ps3av->wq) ++ destroy_workqueue(ps3av->wq); ++ kfree(ps3av); ++ ps3av = NULL; + } + ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + return 0; + } + +-static void ps3av_shutdown(struct ps3_vuart_port_device *dev) ++static void ps3av_shutdown(struct ps3_system_bus_device *dev) + { ++ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); + ps3av_remove(dev); ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + } + + static struct ps3_vuart_port_driver ps3av_driver = { +- .match_id = PS3_MATCH_ID_AV_SETTINGS, + .core = { +- .name = "ps3_av", ++ .match_id = PS3_MATCH_ID_AV_SETTINGS, ++ .core = {.name = "ps3_av",}, + }, + .probe = ps3av_probe, + .remove = ps3av_remove, +@@ -972,6 +994,8 @@ static int ps3av_module_init(void) + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return -ENODEV; + ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ + error = ps3_vuart_port_driver_register(&ps3av_driver); + if (error) { + printk(KERN_ERR +@@ -980,20 +1004,21 @@ static int ps3av_module_init(void) + return error; + } + +- error = ps3_vuart_port_device_register(&ps3av_dev); +- if (error) +- printk(KERN_ERR +- "%s: ps3_vuart_port_device_register failed %d\n", +- __func__, error); +- ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); + return error; + } + + static void __exit ps3av_module_exit(void) + { +- device_unregister(&ps3av_dev.core); ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); + ps3_vuart_port_driver_unregister(&ps3av_driver); ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); + } + + subsys_initcall(ps3av_module_init); + module_exit(ps3av_module_exit); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("PS3 AV Settings Driver"); ++MODULE_AUTHOR("Sony Computer Entertainment Inc."); ++MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS); +--- a/drivers/ps3/ps3av_cmd.c ++++ b/drivers/ps3/ps3av_cmd.c +@@ -868,7 +868,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt + { + int res; + +- ps3fb_flip_ctl(0); /* flip off */ ++ ps3av_flip_ctl(0); /* flip off */ + + /* avb packet */ + res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb), +@@ -882,7 +882,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt + res); + + out: +- ps3fb_flip_ctl(1); /* flip on */ ++ ps3av_flip_ctl(1); /* flip on */ + return res; + } + +@@ -1003,34 +1003,3 @@ void ps3av_cmd_av_monitor_info_dump(cons + | PS3AV_CMD_AV_LAYOUT_176 \ + | PS3AV_CMD_AV_LAYOUT_192) + +-/************************* vuart ***************************/ +- +-#define POLLING_INTERVAL 25 /* in msec */ +- +-int ps3av_vuart_write(struct ps3_vuart_port_device *dev, const void *buf, +- unsigned long size) +-{ +- int error = ps3_vuart_write(dev, buf, size); +- return error ? error : size; +-} +- +-int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, +- unsigned long size, int timeout) +-{ +- int error; +- int loopcnt = 0; +- +- timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL; +- while (loopcnt++ <= timeout) { +- error = ps3_vuart_read(dev, buf, size); +- if (!error) +- return size; +- if (error != -EAGAIN) { +- printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", +- __func__, error); +- return error; +- } +- msleep(POLLING_INTERVAL); +- } +- return -EWOULDBLOCK; +-} +--- a/include/asm-powerpc/ps3av.h ++++ b/include/asm-powerpc/ps3av.h +@@ -1,20 +1,23 @@ + /* +- * Copyright (C) 2006 Sony Computer Entertainment Inc. +- * Copyright 2006, 2007 Sony Corporation ++ * PS3 AV backend support. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published +- * by the Free Software Foundation; version 2 of the License. ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. + * +- * 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. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. + * +- * 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., +- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ ++ + #ifndef _ASM_POWERPC_PS3AV_H_ + #define _ASM_POWERPC_PS3AV_H_ + +@@ -705,12 +708,6 @@ static inline void ps3av_cmd_av_monitor_ + extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *, + u32); + +-struct ps3_vuart_port_device; +-extern int ps3av_vuart_write(struct ps3_vuart_port_device *dev, +- const void *buf, unsigned long size); +-extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, +- unsigned long size, int timeout); +- + extern int ps3av_set_video_mode(u32, int); + extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); + extern int ps3av_get_auto_mode(int); +@@ -723,6 +720,9 @@ extern int ps3av_video_mute(int); + extern int ps3av_audio_mute(int); + extern int ps3av_dev_open(void); + extern int ps3av_dev_close(void); ++extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), ++ void *flip_data); ++extern void ps3av_flip_ctl(int on); + + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_PS3AV_H_ */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/42-ps3stor_flash_bootmem.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/42-ps3stor_flash_bootmem.patch @@ -0,0 +1,71 @@ +Subject: ps3: Preallocate bootmem memory for the PS3 FLASH ROM storage driver + +Preallocate 256 KiB of bootmem memory for the PS3 FLASH ROM storage driver. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/setup.c | 19 ++++++++++++++++++- + include/asm-powerpc/ps3.h | 1 + + 2 files changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -99,7 +99,8 @@ static void ps3_panic(char *str) + while(1); + } + +-#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) ++#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ ++ defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) + static void prealloc(struct ps3_prealloc *p) + { + if (!p->size) +@@ -115,7 +116,9 @@ static void prealloc(struct ps3_prealloc + printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, + p->address); + } ++#endif + ++#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) + struct ps3_prealloc ps3fb_videomemory = { + .name = "ps3fb videomemory", + .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, +@@ -138,6 +141,18 @@ early_param("ps3fb", early_parse_ps3fb); + #define prealloc_ps3fb_videomemory() do { } while (0) + #endif + ++#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) ++struct ps3_prealloc ps3flash_bounce_buffer = { ++ .name = "ps3flash bounce buffer", ++ .size = 256*1024, ++ .align = 256*1024 ++}; ++EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer); ++#define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer) ++#else ++#define prealloc_ps3flash_bounce_buffer() do { } while (0) ++#endif ++ + static int ps3_set_dabr(u64 dabr) + { + enum {DABR_USER = 1, DABR_KERNEL = 2,}; +@@ -167,6 +182,8 @@ static void __init ps3_setup_arch(void) + #endif + + prealloc_ps3fb_videomemory(); ++ prealloc_ps3flash_bounce_buffer(); ++ + ppc_md.power_save = ps3_power_save; + + DBG(" <- %s:%d\n", __func__, __LINE__); +--- a/include/asm-powerpc/ps3.h ++++ b/include/asm-powerpc/ps3.h +@@ -435,6 +435,7 @@ struct ps3_prealloc { + }; + + extern struct ps3_prealloc ps3fb_videomemory; ++extern struct ps3_prealloc ps3flash_bounce_buffer; + + + #endif --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/10-ps3-kexec-fixes.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/10-ps3-kexec-fixes.patch @@ -0,0 +1,264 @@ +Subject: PS3: Kexec support + +Fixup the core platform parts needed for kexec to work on the PS3. + - Setup ps3_hpte_clear correctly. + - Mask interrupts on irq removal. + - Release all hypervisor resources. + - Create new routine ps3_shutdown_IRQ() + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/htab.c | 13 ++++-- + arch/powerpc/platforms/ps3/interrupt.c | 68 +++++++++++++++++++++++++-------- + arch/powerpc/platforms/ps3/platform.h | 1 + arch/powerpc/platforms/ps3/setup.c | 29 ++------------ + arch/powerpc/platforms/ps3/smp.c | 2 + 5 files changed, 70 insertions(+), 43 deletions(-) + +--- a/arch/powerpc/platforms/ps3/htab.c ++++ b/arch/powerpc/platforms/ps3/htab.c +@@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned + + static void ps3_hpte_clear(void) + { +- /* Make sure to clean up the frame buffer device first */ +- ps3fb_cleanup(); ++ int result; + +- lv1_unmap_htab(htab_addr); ++ DBG(" -> %s:%d\n", __func__, __LINE__); ++ ++ result = lv1_unmap_htab(htab_addr); ++ BUG_ON(result); ++ ++ ps3_mm_shutdown(); ++ ps3_mm_vas_destroy(); ++ ++ DBG(" <- %s:%d\n", __func__, __LINE__); + } + + void __init ps3_hpte_init(unsigned long htab_size) +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -220,6 +220,8 @@ int ps3_virq_setup(enum ps3_cpu_binding + goto fail_set; + } + ++ ps3_chip_mask(*virq); ++ + return result; + + fail_set: +@@ -311,6 +313,8 @@ int ps3_irq_plug_destroy(unsigned int vi + pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, + pd->node, pd->cpu, virq); + ++ ps3_chip_mask(virq); ++ + result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); + + if (result) +@@ -368,7 +372,9 @@ int ps3_event_receive_port_destroy(unsig + { + int result; + +- pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); ++ pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); ++ ++ ps3_chip_mask(virq); + + result = lv1_destruct_event_receive_port(virq_to_hw(virq)); + +@@ -376,17 +382,14 @@ int ps3_event_receive_port_destroy(unsig + pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", + __func__, __LINE__, ps3_result(result)); + +- /* lv1_destruct_event_receive_port() destroys the IRQ plug, +- * so don't call ps3_irq_plug_destroy() here. ++ /* ++ * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu() ++ * calls from interrupt context (smp_call_function) when kexecing. + */ + +- result = ps3_virq_destroy(virq); +- BUG_ON(result); +- + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; + } +-EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy); + + int ps3_send_event_locally(unsigned int virq) + { +@@ -458,6 +461,14 @@ int ps3_sb_event_receive_port_destroy(co + result = ps3_event_receive_port_destroy(virq); + BUG_ON(result); + ++ /* ++ * ps3_event_receive_port_destroy() destroys the IRQ plug, ++ * so don't call ps3_irq_plug_destroy() here. ++ */ ++ ++ result = ps3_virq_destroy(virq); ++ BUG_ON(result); ++ + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; + } +@@ -498,16 +509,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup); + int ps3_io_irq_destroy(unsigned int virq) + { + int result; ++ unsigned long outlet = virq_to_hw(virq); + +- result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); ++ ps3_chip_mask(virq); + +- if (result) +- pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", +- __func__, __LINE__, ps3_result(result)); ++ /* ++ * lv1_destruct_io_irq_outlet() will destroy the IRQ plug, ++ * so call ps3_irq_plug_destroy() first. ++ */ + + result = ps3_irq_plug_destroy(virq); + BUG_ON(result); + ++ result = lv1_destruct_io_irq_outlet(outlet); ++ ++ if (result) ++ pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ + return result; + } + EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); +@@ -552,6 +571,7 @@ int ps3_vuart_irq_destroy(unsigned int v + { + int result; + ++ ps3_chip_mask(virq); + result = lv1_deconfigure_virtual_uart_irq(); + + if (result) { +@@ -600,9 +620,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_bindi + + int ps3_spe_irq_destroy(unsigned int virq) + { +- int result = ps3_irq_plug_destroy(virq); ++ int result; ++ ++ ps3_chip_mask(virq); ++ ++ result = ps3_irq_plug_destroy(virq); + BUG_ON(result); +- return 0; ++ ++ return result; + } + + +@@ -662,7 +687,7 @@ static int ps3_host_map(struct irq_host + pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, + virq); + +- set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); ++ set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); + + return 0; + } +@@ -682,7 +707,7 @@ void __init ps3_register_ipi_debug_brk(u + cpu, virq, pd->bmp.ipi_debug_brk_mask); + } + +-unsigned int ps3_get_irq(void) ++static unsigned int ps3_get_irq(void) + { + struct ps3_private *pd = &__get_cpu_var(ps3_private); + u64 x = (pd->bmp.status & pd->bmp.mask); +@@ -747,3 +772,16 @@ void __init ps3_init_IRQ(void) + + ppc_md.get_irq = ps3_get_irq; + } ++ ++void ps3_shutdown_IRQ(int cpu) ++{ ++ int result; ++ u64 ppe_id; ++ u64 thread_id = get_hard_smp_processor_id(cpu); ++ ++ lv1_get_logical_ppe_id(&ppe_id); ++ result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0); ++ ++ DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__, ++ __LINE__, ppe_id, thread_id, cpu, ps3_result(result)); ++} +--- a/arch/powerpc/platforms/ps3/platform.h ++++ b/arch/powerpc/platforms/ps3/platform.h +@@ -41,6 +41,7 @@ void ps3_mm_shutdown(void); + /* irq */ + + void ps3_init_IRQ(void); ++void ps3_shutdown_IRQ(int cpu); + void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); + + /* smp */ +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -209,31 +209,12 @@ static int __init ps3_probe(void) + #if defined(CONFIG_KEXEC) + static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) + { +- DBG(" -> %s:%d\n", __func__, __LINE__); ++ int cpu = smp_processor_id(); + +- if (secondary) { +- int cpu; +- for_each_online_cpu(cpu) +- if (cpu) +- ps3_smp_cleanup_cpu(cpu); +- } else +- ps3_smp_cleanup_cpu(0); ++ DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + +- DBG(" <- %s:%d\n", __func__, __LINE__); +-} +- +-static void ps3_machine_kexec(struct kimage *image) +-{ +- unsigned long ppe_id; +- +- DBG(" -> %s:%d\n", __func__, __LINE__); +- +- lv1_get_logical_ppe_id(&ppe_id); +- lv1_configure_irq_state_bitmap(ppe_id, 0, 0); +- ps3_mm_shutdown(); +- ps3_mm_vas_destroy(); +- +- default_machine_kexec(image); ++ ps3_smp_cleanup_cpu(cpu); ++ ps3_shutdown_IRQ(cpu); + + DBG(" <- %s:%d\n", __func__, __LINE__); + } +@@ -255,7 +236,7 @@ define_machine(ps3) { + .power_off = ps3_power_off, + #if defined(CONFIG_KEXEC) + .kexec_cpu_down = ps3_kexec_cpu_down, +- .machine_kexec = ps3_machine_kexec, ++ .machine_kexec = default_machine_kexec, + .machine_kexec_prepare = default_machine_kexec_prepare, + .machine_crash_shutdown = default_machine_crash_shutdown, + #endif +--- a/arch/powerpc/platforms/ps3/smp.c ++++ b/arch/powerpc/platforms/ps3/smp.c +@@ -138,7 +138,7 @@ void ps3_smp_cleanup_cpu(int cpu) + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + + for (i = 0; i < MSG_COUNT; i++) { +- free_irq(virqs[i], (void*)(long)i); ++ /* Can't call free_irq from interrupt context. */ + ps3_event_receive_port_destroy(virqs[i]); + virqs[i] = NO_IRQ; + } --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/30-powerpc-zimage-global-kernel_entry_t.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/30-powerpc-zimage-global-kernel_entry_t.patch @@ -0,0 +1,33 @@ +Subject: powerpc: Bootwrapper global scope kernel_entry_t. + +For the convenience of custom platform code make the powerpc +bootwrapper typdef kernel_entry_t global in scope. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/main.c | 2 -- + arch/powerpc/boot/ops.h | 2 ++ + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/boot/main.c ++++ b/arch/powerpc/boot/main.c +@@ -36,8 +36,6 @@ struct addr_range { + unsigned long size; + }; + +-typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *); +- + #undef DEBUG + + static struct addr_range prep_kernel(void) +--- a/arch/powerpc/boot/ops.h ++++ b/arch/powerpc/boot/ops.h +@@ -19,6 +19,8 @@ + #define MAX_PATH_LEN 256 + #define MAX_PROP_LEN 256 /* What should this be? */ + ++typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5); ++ + /* Platform specific operations */ + struct platform_ops { + void (*fixups)(void); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/29-powerpc-zimage-const-args.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/29-powerpc-zimage-const-args.patch @@ -0,0 +1,45 @@ +Subject: Powerpc: Fix constantness of bootwrapper arg + +Fixes the constantness of the powerpc bootwrapper's console_ops.write +routine. Allows writing of constant strings. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/of.c | 2 +- + arch/powerpc/boot/ops.h | 2 +- + arch/powerpc/boot/serial.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/boot/of.c ++++ b/arch/powerpc/boot/of.c +@@ -261,7 +261,7 @@ static int of_console_open(void) + return -1; + } + +-static void of_console_write(char *buf, int len) ++static void of_console_write(const char *buf, int len) + { + call_prom("write", 3, 1, of_stdout_handle, buf, len); + } +--- a/arch/powerpc/boot/ops.h ++++ b/arch/powerpc/boot/ops.h +@@ -51,7 +51,7 @@ extern struct dt_ops dt_ops; + /* Console operations */ + struct console_ops { + int (*open)(void); +- void (*write)(char *buf, int len); ++ void (*write)(const char *buf, int len); + void (*edit_cmdline)(char *buf, int len); + void (*close)(void); + void *data; +--- a/arch/powerpc/boot/serial.c ++++ b/arch/powerpc/boot/serial.c +@@ -27,7 +27,7 @@ static int serial_open(void) + return scdp->open(); + } + +-static void serial_write(char *buf, int len) ++static void serial_write(const char *buf, int len) + { + struct serial_console_data *scdp = console_ops.data; + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/15-ps3-system-bus-rework-usb.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/15-ps3-system-bus-rework-usb.patch @@ -0,0 +1,425 @@ +Subject: PS3: USB system-bus rework + +USB HCD glue updates to reflect the new PS3 unified device support. + - Fixed remove() routine. + - Added shutdown() routine. + - Added request_mem_region() call. + - Fixed MODULE_ALIAS(). + - Made a proper fix for the hack done to support muti-platform in commit + 48fda45120a819ca40cadc50144b55bff1c4c78d. + +Signed-off-by: Geoff Levand +--- + drivers/usb/host/ehci-hcd.c | 22 +++-------- + drivers/usb/host/ehci-ps3.c | 86 +++++++++++++++++++++++++++++++++++++------ + drivers/usb/host/ohci-hcd.c | 20 +++------- + drivers/usb/host/ohci-ps3.c | 87 +++++++++++++++++++++++++++++++++++++------- + 4 files changed, 162 insertions(+), 53 deletions(-) +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -41,10 +41,6 @@ + #include + #include + #include +-#ifdef CONFIG_PPC_PS3 +-#include +-#endif +- + + /*-------------------------------------------------------------------------*/ + +@@ -937,7 +933,7 @@ MODULE_LICENSE ("GPL"); + + #ifdef CONFIG_PPC_PS3 + #include "ehci-ps3.c" +-#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_sb_driver ++#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver + #endif + + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ +@@ -971,18 +967,15 @@ static int __init ehci_hcd_init(void) + #endif + + #ifdef PS3_SYSTEM_BUS_DRIVER +- if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { +- retval = ps3_system_bus_driver_register( +- &PS3_SYSTEM_BUS_DRIVER); +- if (retval < 0) { ++ retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER); ++ if (retval < 0) { + #ifdef PLATFORM_DRIVER +- platform_driver_unregister(&PLATFORM_DRIVER); ++ platform_driver_unregister(&PLATFORM_DRIVER); + #endif + #ifdef PCI_DRIVER +- pci_unregister_driver(&PCI_DRIVER); ++ pci_unregister_driver(&PCI_DRIVER); + #endif +- return retval; +- } ++ return retval; + } + #endif + +@@ -999,8 +992,7 @@ static void __exit ehci_hcd_cleanup(void + pci_unregister_driver(&PCI_DRIVER); + #endif + #ifdef PS3_SYSTEM_BUS_DRIVER +- if (firmware_has_feature(FW_FEATURE_PS3_LV1)) +- ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ++ ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); + #endif + } + module_exit(ehci_hcd_cleanup); +--- a/drivers/usb/host/ehci-ps3.c ++++ b/drivers/usb/host/ehci-ps3.c +@@ -18,6 +18,7 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#include + #include + + static int ps3_ehci_hc_reset(struct usb_hcd *hcd) +@@ -73,7 +74,7 @@ static const struct hc_driver ps3_ehci_h + #endif + }; + +-static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) ++static int ps3_ehci_probe(struct ps3_system_bus_device *dev) + { + int result; + struct usb_hcd *hcd; +@@ -85,13 +86,30 @@ static int ps3_ehci_sb_probe(struct ps3_ + goto fail_start; + } + ++ result = ps3_open_hv_device(dev); ++ ++ if (result) { ++ dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n", ++ __func__, __LINE__); ++ goto fail_open; ++ } ++ ++ result = ps3_dma_region_create(dev->d_region); ++ ++ if (result) { ++ dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " ++ "(%d)\n", __func__, __LINE__, result); ++ BUG_ON("check region type"); ++ goto fail_dma_region; ++ } ++ + result = ps3_mmio_region_create(dev->m_region); + + if (result) { + dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", + __func__, __LINE__); + result = -EPERM; +- goto fail_mmio; ++ goto fail_mmio_region; + } + + dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, +@@ -120,6 +138,11 @@ static int ps3_ehci_sb_probe(struct ps3_ + + hcd->rsrc_start = dev->m_region->lpar_addr; + hcd->rsrc_len = dev->m_region->len; ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) ++ dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n", ++ __func__, __LINE__); ++ + hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); + + if (!hcd->regs) { +@@ -153,34 +176,73 @@ static int ps3_ehci_sb_probe(struct ps3_ + fail_add_hcd: + iounmap(hcd->regs); + fail_ioremap: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + fail_create_hcd: + ps3_io_irq_destroy(virq); + fail_irq: + ps3_free_mmio_region(dev->m_region); +-fail_mmio: ++fail_mmio_region: ++ ps3_dma_region_free(dev->d_region); ++fail_dma_region: ++ ps3_close_hv_device(dev); ++fail_open: + fail_start: + return result; + } + +-static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev) ++static int ps3_ehci_remove(struct ps3_system_bus_device *dev) + { ++ unsigned int tmp; + struct usb_hcd *hcd = + (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); + +- usb_put_hcd(hcd); ++ BUG_ON(!hcd); ++ ++ dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs); ++ dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq); ++ ++ tmp = hcd->irq; ++ ++ usb_remove_hcd(hcd); ++ + ps3_system_bus_set_driver_data(dev, NULL); + ++ BUG_ON(!hcd->regs); ++ iounmap(hcd->regs); ++ ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); ++ ++ ps3_io_irq_destroy(tmp); ++ ps3_free_mmio_region(dev->m_region); ++ ++ ps3_dma_region_free(dev->d_region); ++ ps3_close_hv_device(dev); ++ + return 0; + } + +-MODULE_ALIAS("ps3-ehci"); ++static int ps3_ehci_driver_register(struct ps3_system_bus_driver *drv) ++{ ++ return firmware_has_feature(FW_FEATURE_PS3_LV1) ++ ? ps3_system_bus_driver_register(drv) ++ : -ENODEV; ++} ++ ++static void ps3_ehci_driver_unregister(struct ps3_system_bus_driver *drv) ++{ ++ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) ++ ps3_system_bus_driver_unregister(drv); ++} ++ ++MODULE_ALIAS(PS3_MODULE_ALIAS_EHCI); + +-static struct ps3_system_bus_driver ps3_ehci_sb_driver = { ++static struct ps3_system_bus_driver ps3_ehci_driver = { ++ .core.name = "ps3-ehci-driver", ++ .core.owner = THIS_MODULE, + .match_id = PS3_MATCH_ID_EHCI, +- .core = { +- .name = "ps3-ehci-driver", +- }, +- .probe = ps3_ehci_sb_probe, +- .remove = ps3_ehci_sb_remove, ++ .probe = ps3_ehci_probe, ++ .remove = ps3_ehci_remove, ++ .shutdown = ps3_ehci_remove, + }; +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -41,9 +41,6 @@ + #include + #include + #include +-#ifdef CONFIG_PPC_PS3 +-#include +-#endif + + #include "../core/hcd.h" + +@@ -917,7 +914,7 @@ MODULE_LICENSE ("GPL"); + + #ifdef CONFIG_PPC_PS3 + #include "ohci-ps3.c" +-#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_sb_driver ++#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver + #endif + + #if !defined(PCI_DRIVER) && \ +@@ -940,12 +937,9 @@ static int __init ohci_hcd_mod_init(void + sizeof (struct ed), sizeof (struct td)); + + #ifdef PS3_SYSTEM_BUS_DRIVER +- if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { +- retval = ps3_system_bus_driver_register( +- &PS3_SYSTEM_BUS_DRIVER); +- if (retval < 0) +- goto error_ps3; +- } ++ retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER); ++ if (retval < 0) ++ goto error_ps3; + #endif + + #ifdef PLATFORM_DRIVER +@@ -991,8 +985,7 @@ static int __init ohci_hcd_mod_init(void + error_platform: + #endif + #ifdef PS3_SYSTEM_BUS_DRIVER +- if (firmware_has_feature(FW_FEATURE_PS3_LV1)) +- ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ++ ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); + error_ps3: + #endif + return retval; +@@ -1014,8 +1007,7 @@ static void __exit ohci_hcd_mod_exit(voi + platform_driver_unregister(&PLATFORM_DRIVER); + #endif + #ifdef PS3_SYSTEM_BUS_DRIVER +- if (firmware_has_feature(FW_FEATURE_PS3_LV1)) +- ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ++ ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); + #endif + } + module_exit(ohci_hcd_mod_exit); +--- a/drivers/usb/host/ohci-ps3.c ++++ b/drivers/usb/host/ohci-ps3.c +@@ -18,6 +18,7 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#include + #include + + static int ps3_ohci_hc_reset(struct usb_hcd *hcd) +@@ -75,7 +76,7 @@ static const struct hc_driver ps3_ohci_h + #endif + }; + +-static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) ++static int ps3_ohci_probe(struct ps3_system_bus_device *dev) + { + int result; + struct usb_hcd *hcd; +@@ -87,13 +88,31 @@ static int ps3_ohci_sb_probe(struct ps3_ + goto fail_start; + } + ++ result = ps3_open_hv_device(dev); ++ ++ if (result) { ++ dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed: %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ result = -EPERM; ++ goto fail_open; ++ } ++ ++ result = ps3_dma_region_create(dev->d_region); ++ ++ if (result) { ++ dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " ++ "(%d)\n", __func__, __LINE__, result); ++ BUG_ON("check region type"); ++ goto fail_dma_region; ++ } ++ + result = ps3_mmio_region_create(dev->m_region); + + if (result) { + dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", + __func__, __LINE__); + result = -EPERM; +- goto fail_mmio; ++ goto fail_mmio_region; + } + + dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, +@@ -122,6 +141,11 @@ static int ps3_ohci_sb_probe(struct ps3_ + + hcd->rsrc_start = dev->m_region->lpar_addr; + hcd->rsrc_len = dev->m_region->len; ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) ++ dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n", ++ __func__, __LINE__); ++ + hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); + + if (!hcd->regs) { +@@ -155,34 +179,73 @@ static int ps3_ohci_sb_probe(struct ps3_ + fail_add_hcd: + iounmap(hcd->regs); + fail_ioremap: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + fail_create_hcd: + ps3_io_irq_destroy(virq); + fail_irq: + ps3_free_mmio_region(dev->m_region); +-fail_mmio: ++fail_mmio_region: ++ ps3_dma_region_free(dev->d_region); ++fail_dma_region: ++ ps3_close_hv_device(dev); ++fail_open: + fail_start: + return result; + } + +-static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev) ++static int ps3_ohci_remove (struct ps3_system_bus_device *dev) + { ++ unsigned int tmp; + struct usb_hcd *hcd = + (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); + +- usb_put_hcd(hcd); ++ BUG_ON(!hcd); ++ ++ dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs); ++ dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq); ++ ++ tmp = hcd->irq; ++ ++ usb_remove_hcd(hcd); ++ + ps3_system_bus_set_driver_data(dev, NULL); + ++ BUG_ON(!hcd->regs); ++ iounmap(hcd->regs); ++ ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); ++ ++ ps3_io_irq_destroy(tmp); ++ ps3_free_mmio_region(dev->m_region); ++ ++ ps3_dma_region_free(dev->d_region); ++ ps3_close_hv_device(dev); ++ + return 0; + } + +-MODULE_ALIAS("ps3-ohci"); ++static int ps3_ohci_driver_register(struct ps3_system_bus_driver *drv) ++{ ++ return firmware_has_feature(FW_FEATURE_PS3_LV1) ++ ? ps3_system_bus_driver_register(drv) ++ : -ENODEV; ++} ++ ++static void ps3_ohci_driver_unregister(struct ps3_system_bus_driver *drv) ++{ ++ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) ++ ps3_system_bus_driver_unregister(drv); ++} ++ ++MODULE_ALIAS(PS3_MODULE_ALIAS_OHCI); + +-static struct ps3_system_bus_driver ps3_ohci_sb_driver = { ++static struct ps3_system_bus_driver ps3_ohci_driver = { ++ .core.name = "ps3-ohci-driver", ++ .core.owner = THIS_MODULE, + .match_id = PS3_MATCH_ID_OHCI, +- .core = { +- .name = "ps3-ohci-driver", +- }, +- .probe = ps3_ohci_sb_probe, +- .remove = ps3_ohci_sb_remove, ++ .probe = ps3_ohci_probe, ++ .remove = ps3_ohci_remove, ++ .shutdown = ps3_ohci_remove, + }; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/47-ps3-sound.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/47-ps3-sound.patch @@ -0,0 +1,2414 @@ +--- + sound/ppc/Kconfig | 20 + sound/ppc/Makefile | 3 + sound/ppc/snd_ps3.c | 1299 ++++++++++++++++++++++++++++++++++++++++++++++++ + sound/ppc/snd_ps3.h | 207 +++++++ + sound/ppc/snd_ps3_reg.h | 856 +++++++++++++++++++++++++++++++ + 5 files changed, 2384 insertions(+), 1 deletion(-) + +--- a/sound/ppc/Kconfig ++++ b/sound/ppc/Kconfig +@@ -33,3 +33,23 @@ config SND_POWERMAC_AUTO_DRC + option. + + endmenu ++ ++menu "ALSA PowerPC devices" ++ depends on SND!=n && ( PPC64 || PPC32 ) ++ ++config SND_PS3 ++ tristate "PS3 Audio support" ++ depends on SND && PS3_PS3AV ++ select SND_PCM ++ default m ++ help ++ Say Y here to include support for audio on the PS3 ++ ++ To compile this driver as a module, choose M here: the module ++ will be called snd_ps3. ++ ++config SND_PS3_DEFAULT_START_DELAY ++ int "Startup delay time in ms" ++ depends on SND_PS3 ++ default "2000" ++endmenu +--- a/sound/ppc/Makefile ++++ b/sound/ppc/Makefile +@@ -6,4 +6,5 @@ + snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o + + # Toplevel Module Dependency +-obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o ++obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o ++obj-$(CONFIG_SND_PS3) += snd_ps3.o +--- /dev/null ++++ b/sound/ppc/snd_ps3.c +@@ -0,0 +1,1299 @@ ++/* ++ * Audio support for PS3 ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * All rights reserved. ++ * Copyright 2006, 2007 Sony Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; version 2 of the Licence. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#define DEBUG ++#undef _SND_PS3_DEV_ATTR ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "snd_ps3_reg.h" ++#include "snd_ps3.h" ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("PS3 sound driver"); ++MODULE_AUTHOR("Sony Computer Entertainment Inc."); ++ ++static int index = SNDRV_DEFAULT_IDX1; ++static char *id = SNDRV_DEFAULT_STR1; ++ ++module_param(index, int, 0444); ++MODULE_PARM_DESC(index, "Index value for PS3 soundchip."); ++module_param(id, charp, 0444); ++MODULE_PARM_DESC(id, "ID string for PS3 soundchip."); ++ ++ ++module_init(snd_ps3_init); ++module_exit(snd_ps3_exit); ++ ++ ++#ifdef _SND_PS3_DEV_ATTR ++static DEVICE_ATTR(start_delay, ++ S_IRUGO | S_IWUSR, ++ snd_ps3_get_start_delay, ++ snd_ps3_set_start_delay); ++#endif ++ ++/* ++ * global ++ */ ++static struct snd_ps3_card_info the_card; ++ ++static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; ++ ++module_param_named(start_delay, snd_ps3_start_delay, int, 0444); ++MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); ++ ++/* ++ * PS3 audio register access macros ++ */ ++ ++/* ++ * chip: pointer to snd_ps3_card_info ++ * name: register offset value; PS3_AUDIO_XXXX ++ */ ++#define AUDIOREGPTR(chip, name) \ ++ (volatile uint32_t *)(chip->mapped_mmio_vaddr + name) ++ ++#define AUDIOREG(chip, name) *(AUDIOREGPTR(chip, name)) ++ ++/* ++ * ALSA defs ++ */ ++const static struct snd_pcm_hardware snd_ps3_pcm_hw = { ++ .info = (SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_NONINTERLEAVED | ++ SNDRV_PCM_INFO_MMAP_VALID), ++ .formats = (SNDRV_PCM_FMTBIT_S16_BE | ++ SNDRV_PCM_FMTBIT_S24_BE), ++ .rates = (SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_88200 | ++ SNDRV_PCM_RATE_96000), ++ .rate_min = 44100, ++ .rate_max = 96000, ++ ++ .channels_min = 2, /* stereo only */ ++ .channels_max = 2, ++ ++ .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64, ++ ++ /* interrupt by four stages */ ++ .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4, ++ .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4, ++ ++ .periods_min = 16, ++ .periods_max = 32, /* buffer_size_max/ period_bytes_max */ ++ ++ .fifo_size = PS3_AUDIO_FIFO_SIZE ++}; ++ ++static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = ++{ ++ .open = snd_ps3_pcm_open, ++ .close = snd_ps3_pcm_close, ++ .prepare = snd_ps3_pcm_prepare, ++ .ioctl = snd_pcm_lib_ioctl, ++ .trigger = snd_ps3_pcm_trigger, ++ .pointer = snd_ps3_pcm_pointer, ++ .hw_params = snd_ps3_pcm_hw_params, ++ .hw_free = snd_ps3_pcm_hw_free ++}; ++ ++static struct snd_kcontrol_new snd_ps3_vol_control = ++{ ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "PCM Playback Volume", ++ .index = 0, ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .private_value = SND_PS3_MAX_VOL,/* not used */ ++ .info = snd_ps3_info_vol_control, ++ .put = snd_ps3_put_vol_control, ++ .get = snd_ps3_get_vol_control ++}; ++ ++static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info * card, ++ int count, int force_stop) ++{ ++ int dma_ch, done, retries, stop_forced = 0; ++ uint32_t status; ++ ++ for (dma_ch = 0; dma_ch < 8; dma_ch ++) { ++ retries = count; ++ do { ++ status = AUDIOREG(card, PS3_AUDIO_KICK(dma_ch)) & ++ PS3_AUDIO_KICK_STATUS_MASK; ++ switch (status) { ++ case PS3_AUDIO_KICK_STATUS_DONE: ++ case PS3_AUDIO_KICK_STATUS_NOTIFY: ++ case PS3_AUDIO_KICK_STATUS_CLEAR: ++ case PS3_AUDIO_KICK_STATUS_ERROR: ++ done = 1; ++ break; ++ default: ++ done = 0; ++ udelay(10); ++ } ++ } while (!done && --retries); ++ if (!retries && force_stop) { ++ printk(KERN_ERR "%s: DMA ch %d is not stopped.", ++ __func__, dma_ch); ++ /* last resort. force to stop dma. ++ * NOTE: this cause DMA done interrupts ++ */ ++ AUDIOREG(card, PS3_AUDIO_CONFIG) |= ++ PS3_AUDIO_CONFIG_CLEAR; ++ stop_forced = 1; ++ } ++ } ++ return stop_forced; ++} ++ ++/* ++ * wait for all dma is done. ++ * NOTE: caller should reset card->running before call. ++ * If not, the interrupt handler will re-start DMA, ++ * then DMA is never stopped. ++ */ ++static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info * card) ++{ ++ int stop_forced; ++ /* ++ * wait for the last dma is done ++ */ ++ ++ /* ++ * expected maximum DMA done time is 5.7ms + something (DMA itself). ++ * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next ++ * DMA kick event would occur. ++ */ ++ stop_forced = snd_ps3_verify_dma_stop(card, 700, 1); ++ ++ /* ++ * clear outstanding interrupts. ++ */ ++ AUDIOREG(card, PS3_AUDIO_INTR_0) |= 0; ++ AUDIOREG(card, PS3_AUDIO_AX_IS) |= 0; ++ ++ /* ++ *revert CLEAR bit since it will not reset automatically after DMA stop ++ */ ++ if (stop_forced) { ++ AUDIOREG(card, PS3_AUDIO_CONFIG) &= ~PS3_AUDIO_CONFIG_CLEAR; ++ } ++ mb(); ++} ++ ++static void snd_ps3_kick_dma(struct snd_ps3_card_info * card) ++{ ++ ++ AUDIOREG(card, PS3_AUDIO_KICK(0)) |= PS3_AUDIO_KICK_REQUEST; ++ mb(); ++} ++ ++/* ++ * convert virtual addr to ioif bus addr. ++ */ ++static dma_addr_t v_to_bus(struct snd_ps3_card_info * card, ++ void * paddr, ++ int ch) ++{ ++ return card->dma_start_bus_addr[ch] + ++ (paddr - card->dma_start_vaddr[ch]); ++}; ++ ++ ++/* ++ * increment ring buffer pointer. ++ * NOTE: caller must hold write spinlock ++ */ ++static void snd_ps3_bump_buffer(struct snd_ps3_card_info * card, ++ enum snd_ps3_ch ch, size_t byte_count, ++ int stage) ++{ ++ if (!stage) ++ card->dma_last_transfer_vaddr[ch] = ++ card->dma_next_transfer_vaddr[ch]; ++ card->dma_next_transfer_vaddr[ch] += byte_count; ++ if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <= ++ card->dma_next_transfer_vaddr[ch]) { ++ card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch]; ++ } ++} ++/* ++ * setup dmac to send data to audio and attenuate samples on the ring buffer ++ */ ++static int snd_ps3_program_dma(struct snd_ps3_card_info * card, ++ enum snd_ps3_dma_filltype filltype) ++{ ++ /* this dmac does not support over 4G */ ++ uint32_t dma_addr; ++ int fill_stages, dma_ch, stage; ++ enum snd_ps3_ch ch; ++ uint32_t ch0_kick_event = 0; /* initialize to mute gcc */ ++ void * start_vaddr; ++ unsigned long irqsave; ++ int silent = 0; ++ ++ switch (filltype) { ++ case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL: ++ silent = 1; ++ /* intentionally fall thru */ ++ case SND_PS3_DMA_FILLTYPE_FIRSTFILL: ++ ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS; ++ break; ++ ++ case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING: ++ silent = 1; ++ /* intentionally fall thru */ ++ case SND_PS3_DMA_FILLTYPE_RUNNING: ++ ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY; ++ break; ++ } ++ ++ snd_ps3_verify_dma_stop(card, 700, 0); ++ fill_stages = 4; ++ write_lock_irqsave(&card->dma_lock, irqsave); ++ if (likely(!silent)) ++ snd_ps3_soft_attenuate(card, ++ card->dma_next_transfer_vaddr[0], ++ card->dma_next_transfer_vaddr[1], ++ PS3_AUDIO_DMAC_BLOCK_SIZE * 4); ++ for (ch = 0; ch < 2; ch++) { ++ start_vaddr = card->dma_next_transfer_vaddr[0]; ++ for (stage = 0; stage < fill_stages; stage ++) { ++ //dma_ch = fill_stages * ch + stage; ++ dma_ch = stage * 2 + ch; ++ if (silent) ++ dma_addr = card->null_buffer_start_dma_addr; ++ else ++ dma_addr = ++ v_to_bus(card, ++ card->dma_next_transfer_vaddr[ch], ++ ch); ++ ++ AUDIOREG(card, PS3_AUDIO_SOURCE(dma_ch)) = ++ (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY | ++ dma_addr); ++ ++ /* dst: fixed to 3wire#0 */ ++ if (ch == 0) ++ AUDIOREG(card, PS3_AUDIO_DEST(dma_ch)) = ++ (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | ++ PS3_AUDIO_AO_3W_LDATA(0)); ++ else ++ AUDIOREG(card, PS3_AUDIO_DEST(dma_ch)) = ++ (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | ++ PS3_AUDIO_AO_3W_RDATA(0)); ++ ++ /* count always 1 DMA block (1/2 stage = 128 bytes) */ ++ AUDIOREG(card, PS3_AUDIO_DMASIZE(dma_ch)) = 0; ++ /* bump pointer if needed */ ++ if (!silent) ++ snd_ps3_bump_buffer(card, ch, ++ PS3_AUDIO_DMAC_BLOCK_SIZE, ++ stage); ++ ++ /* kick event */ ++ if (dma_ch == 0) { ++ AUDIOREG(card, PS3_AUDIO_KICK(dma_ch)) = ++ ch0_kick_event; ++ } else { ++ AUDIOREG(card, PS3_AUDIO_KICK(dma_ch)) = ++ (PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch - ++ 1) | ++ PS3_AUDIO_KICK_REQUEST); ++ } ++ } ++ } ++ mb(); ++ write_unlock_irqrestore(&card->dma_lock, irqsave); ++ ++ mb(); ++ return 0; ++} ++ ++/* ++ * audio mute on/off ++ * mute_on : 0 output enabled ++ * 1 mute ++ */ ++static int snd_ps3_mute(int mute_on) ++{ ++ return ps3av_audio_mute(mute_on); ++} ++ ++/* ++ * PCM operators ++ */ ++static int snd_ps3_pcm_open(struct snd_pcm_substream * substream) ++{ ++ struct snd_pcm_runtime * runtime = substream->runtime; ++ struct snd_ps3_card_info * card = snd_pcm_substream_chip(substream); ++ int pcm_index; ++ ++ pcm_index = substream->pcm->device; ++ /* to retrieve substream/runtime in interrupt handler */ ++ card->substream = substream; ++ ++ runtime->hw = snd_ps3_pcm_hw; ++ ++ /* mute off */ ++ snd_ps3_mute(0); // this function sleep ++ ++ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, ++ PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2); ++ return 0; ++}; ++ ++static int snd_ps3_pcm_hw_params(struct snd_pcm_substream * substream, ++ struct snd_pcm_hw_params * hw_params) ++{ ++ size_t size; ++ ++ /* alloc transport buffer */ ++ size = params_buffer_bytes(hw_params); ++ snd_pcm_lib_malloc_pages(substream, size); ++ return 0; ++}; ++ ++static int snd_ps3_delay_to_bytes(struct snd_pcm_substream * substream, ++ unsigned int delay_ms) ++{ ++ int ret; ++ int rate ; ++ ++ rate = substream->runtime->rate; ++ ret = snd_pcm_format_size(substream->runtime->format, ++ rate * delay_ms / 1000) ++ * substream->runtime->channels; ++ ++ pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", ++ __func__, ++ delay_ms, ++ rate, ++ snd_pcm_format_size(substream->runtime->format, rate), ++ rate * delay_ms / 1000, ++ ret); ++ ++ return ret; ++}; ++ ++static int snd_ps3_pcm_prepare(struct snd_pcm_substream * substream) ++{ ++ struct snd_pcm_runtime * runtime = substream->runtime; ++ struct snd_ps3_card_info * card = snd_pcm_substream_chip(substream); ++ unsigned long irqsave; ++ ++ if (!snd_ps3_set_avsetting(substream)) { ++ /* some parameter changed */ ++ AUDIOREG(card, PS3_AUDIO_AX_IE) = (PS3_AUDIO_AX_IE_ASOBEIE(0) | ++ PS3_AUDIO_AX_IE_ASOBUIE(0)); ++ /* ++ * let SPDIF device re-lock with SPDIF signal, ++ * start with some silence ++ */ ++ read_lock(&card->start_delay_lock); ++ card->silent = snd_ps3_delay_to_bytes(substream, ++ card->start_delay) / ++ (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */ ++ read_unlock(&card->start_delay_lock); ++ } ++ ++ /* restart ring buffer pointer */ ++ write_lock_irqsave(&card->dma_lock, irqsave); ++ { ++ card->dma_buffer_size = runtime->dma_bytes; ++ ++ card->dma_last_transfer_vaddr[SND_PS3_CH_L] = ++ card->dma_next_transfer_vaddr[SND_PS3_CH_L] = ++ card->dma_start_vaddr[SND_PS3_CH_L] = ++ runtime->dma_area; ++ card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr; ++ ++ card->dma_last_transfer_vaddr[SND_PS3_CH_R] = ++ card->dma_next_transfer_vaddr[SND_PS3_CH_R] = ++ card->dma_start_vaddr[SND_PS3_CH_R] = ++ runtime->dma_area + (runtime->dma_bytes / 2); ++ card->dma_start_bus_addr[SND_PS3_CH_R] = ++ runtime->dma_addr + (runtime->dma_bytes / 2); ++ ++ pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, ++ card->dma_start_vaddr[SND_PS3_CH_L], ++ card->dma_start_bus_addr[SND_PS3_CH_L]); ++ ++ } ++ write_unlock_irqrestore(&card->dma_lock, irqsave); ++ ++ mb(); ++ ++ return 0; ++}; ++ ++static int snd_ps3_pcm_trigger(struct snd_pcm_substream * substream, ++ int cmd) ++{ ++ struct snd_ps3_card_info * card = snd_pcm_substream_chip(substream); ++ int ret = 0; ++ unsigned long irqsave; ++ ++ switch (cmd) ++ { ++ case SNDRV_PCM_TRIGGER_START: ++ /* clear outstanding interrupts */ ++ AUDIOREG(card, PS3_AUDIO_AX_IS) |= 0; ++ ++ write_lock_irqsave(&card->dma_lock, irqsave); ++ { ++ card->running = 1; ++ } ++ write_unlock_irqrestore(&card->dma_lock, irqsave); ++ ++ snd_ps3_program_dma(card, ++ SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); ++ snd_ps3_kick_dma(card); ++ while (AUDIOREG(card, PS3_AUDIO_KICK(7)) & ++ PS3_AUDIO_KICK_STATUS_MASK) { ++ udelay(1); ++ } ++ snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); ++ snd_ps3_kick_dma(card); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ write_lock_irqsave(&card->dma_lock, irqsave); ++ { ++ card->running = 0; ++ } ++ write_unlock_irqrestore(&card->dma_lock, irqsave); ++ snd_ps3_wait_for_dma_stop(card); ++ break; ++ default: ++ break; ++ ++ } ++ ++ return ret; ++}; ++ ++/* ++ * report current pointer ++ */ ++static snd_pcm_uframes_t snd_ps3_pcm_pointer( ++ struct snd_pcm_substream * substream) ++{ ++ struct snd_ps3_card_info * card = snd_pcm_substream_chip(substream); ++ unsigned long irqsave; ++ size_t bytes; ++ snd_pcm_uframes_t ret; ++ ++ read_lock_irqsave(&card->dma_lock, irqsave); ++ { ++ bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] - ++ card->dma_start_vaddr[SND_PS3_CH_L]); ++ } ++ read_unlock_irqrestore(&card->dma_lock, irqsave); ++ ++ ret = bytes_to_frames(substream->runtime, bytes * 2); ++ ++ return ret; ++}; ++ ++static int snd_ps3_pcm_hw_free(struct snd_pcm_substream * substream) ++{ ++ int ret; ++ ret = snd_pcm_lib_free_pages(substream); ++ return ret; ++}; ++ ++static int snd_ps3_pcm_close(struct snd_pcm_substream * substream) ++{ ++ /* mute on */ ++ snd_ps3_mute(1); ++ return 0; ++}; ++ ++static void snd_ps3_audio_fixup(struct snd_ps3_card_info * card) ++{ ++ /* ++ * avsetting driver seems to never change the followings ++ * so, init them here once ++ */ ++ ++ /* no dma interrupt needed */ ++ AUDIOREG(card, PS3_AUDIO_INTR_EN_0) = 0; ++ ++ /* use every 4 buffer empty interrupt */ ++ AUDIOREG(card, PS3_AUDIO_AX_IC) = ((AUDIOREG(card, PS3_AUDIO_AX_IC) & ++ PS3_AUDIO_AX_IC_AASOIMD_MASK) | ++ PS3_AUDIO_AX_IC_AASOIMD_EVERY4); ++ ++ /* enable 3wire clocks */ ++ AUDIOREG(card, PS3_AUDIO_AO_3WMCTRL) &= ++ ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | ++ PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED); ++ AUDIOREG(card, PS3_AUDIO_AO_3WMCTRL) |= ++ PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT; ++} ++ ++/* ++ * av setting ++ * NOTE: calling this function may generate audio interrupt. ++ */ ++static int snd_ps3_change_avsetting(struct snd_ps3_card_info * card) ++{ ++ int ret, retries, i; ++ ++ ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, ++ card->avs.avs_audio_rate, ++ card->avs.avs_audio_width, ++ card->avs.avs_audio_format, ++ card->avs.avs_audio_source); ++ /* ++ * Reset the following unwanted settings: ++ */ ++ ++ /* disable all 3wire buffers */ ++ AUDIOREG(card, PS3_AUDIO_AO_3WMCTRL) &= ++ ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | ++ PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | ++ PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | ++ PS3_AUDIO_AO_3WMCTRL_ASOEN(3)); ++ mb(); ++ /* wait for actually stopped */ ++ retries = 1000; ++ while ((AUDIOREG(card, PS3_AUDIO_AO_3WMCTRL) & ++ (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | ++ PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | ++ PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | ++ PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && ++ --retries) { ++ udelay(1); ++ } ++ mb(); ++ /* reset buffer pointer */ ++ for (i = 0; i < 4; i++) { ++ AUDIOREG(card, PS3_AUDIO_AO_3WCTRL(i)) |= ++ PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET; ++ udelay(10); ++ } ++ mb(); ++ ++ /* enable 3wire#0 buffer */ ++ AUDIOREG(card, PS3_AUDIO_AO_3WMCTRL) |= PS3_AUDIO_AO_3WMCTRL_ASOEN(0); ++ mb(); ++ ++ /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ ++ AUDIOREG(card, PS3_AUDIO_AO_3WCTRL(0)) = ++ ((AUDIOREG(card, PS3_AUDIO_AO_3WCTRL(0)) & ++ ~PS3_AUDIO_AO_3WCTRL_ASODF) | ++ PS3_AUDIO_AO_3WCTRL_ASODF_LSB); ++ AUDIOREG(card, PS3_AUDIO_AO_SPDCTRL(0)) = ++ ((AUDIOREG(card, PS3_AUDIO_AO_SPDCTRL(0)) & ++ ~PS3_AUDIO_AO_SPDCTRL_SPODF) | ++ PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); ++ mb(); ++ /* avsetting driver altered AX_IE, caller must reset it if you want */ ++ return ret; ++} ++ ++static int snd_ps3_init_avsetting(struct snd_ps3_card_info * card) ++{ ++ int ret; ++ ++ card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; ++ card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; ++ card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; ++ card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; ++ card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; ++ ++ ret = snd_ps3_change_avsetting(card); ++ ++ snd_ps3_audio_fixup(card); ++ ++ /* to start to generate SPDIF signal, fill data */ ++ snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); ++ snd_ps3_kick_dma(card); ++ return ret; ++} ++ ++/* ++ * set sampling rate according to the substream ++ */ ++static int snd_ps3_set_avsetting(struct snd_pcm_substream * substream) ++{ ++ struct snd_ps3_card_info * card = snd_pcm_substream_chip(substream); ++ struct snd_ps3_avsetting_info avs; ++ ++ avs = card->avs; ++ ++ pr_debug("%s: called freq=%d width=%d\n", __func__, ++ substream->runtime->rate, ++ snd_pcm_format_width(substream->runtime->format)); ++ ++ pr_debug("%s: before freq=%d width=%d\n", __func__, ++ card->avs.avs_audio_rate, card->avs.avs_audio_width); ++ ++ /* sample rate */ ++ switch (substream->runtime->rate) ++ { ++ case 44100: ++ avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; ++ break; ++ case 48000: ++ avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; ++ break; ++ case 88200: ++ avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; ++ break; ++ case 96000: ++ avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; ++ break; ++ default: ++ printk(KERN_ERR "%s: invalid rate %d\n", __func__, ++ substream->runtime->rate); ++ return 1; ++ } ++ ++ /* width */ ++ switch (snd_pcm_format_width(substream->runtime->format)) ++ { ++ case 16: ++ avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; ++ break; ++ case 24: ++ avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; ++ break; ++ default: ++ printk(KERN_ERR "%s: invalid width %d\n", __func__, ++ snd_pcm_format_width(substream->runtime->format)); ++ return 1; ++ } ++ ++ if ((card->avs.avs_audio_width != avs.avs_audio_width) || ++ (card->avs.avs_audio_rate != avs.avs_audio_rate)) { ++ card->avs = avs; ++ snd_ps3_change_avsetting(card); ++ ++ pr_debug("%s: after freq=%d width=%d\n", __func__, ++ card->avs.avs_audio_rate, card->avs.avs_audio_width); ++ ++ return 0; ++ } else ++ return 1; ++} ++ ++ ++ ++static int snd_ps3_map_mmio(void) ++{ ++ the_card.mapped_mmio_vaddr = ++ ioremap(the_card.ps3_dev->m_region->bus_addr, ++ the_card.ps3_dev->m_region->len); ++ ++ if (!the_card.mapped_mmio_vaddr) { ++ printk(KERN_ERR "%s: ioremap 0 failed p=%#lx l=%#lx \n", ++ __func__, the_card.ps3_dev->m_region->lpar_addr, ++ the_card.ps3_dev->m_region->len); ++ return -ENXIO; ++ } ++ ++ return 0; ++}; ++ ++static void snd_ps3_unmap_mmio(void) ++{ ++ iounmap(the_card.mapped_mmio_vaddr); ++ the_card.mapped_mmio_vaddr = NULL; ++} ++ ++static int snd_ps3_allocate_irq(void) ++{ ++ int ret; ++ u64 lpar_addr, lpar_size; ++ u64 * mapped; ++ ++ // FIXME: move this to device_init (H/W probe) ++ ++ /* get irq outlet */ ++ ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size); ++ if (ret) { ++ printk(KERN_ERR "%s: device map 1 failed %d\n", __func__, ++ ret); ++ return -ENXIO; ++ } ++ ++ mapped = ioremap(lpar_addr, lpar_size); ++ ++ if (!mapped) { ++ printk(KERN_ERR "%s: ioremap 1 failed \n", __func__); ++ return -ENXIO; ++ } ++ ++ the_card.audio_irq_outlet = *mapped; ++ ++ iounmap(mapped); ++ lv1_gpu_device_unmap(1); ++ ++ /* irq */ ++ ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, ++ the_card.audio_irq_outlet, ++ &the_card.irq_no); ++ if (ret) { ++ printk("%s:ps3_alloc_irq failed (%d)\n", __func__, ret); ++ return ret; ++ } ++ ++ ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, ++ SND_PS3_DRIVER_NAME, &the_card); ++ if (ret) { ++ printk("%s: request_irq failed (%d)\n", __func__, ret); ++ goto cleanup_irq; ++ } ++ ++ return 0; ++ ++ cleanup_irq: ++ ps3_irq_plug_destroy(the_card.irq_no); ++ return ret; ++}; ++ ++static void snd_ps3_free_irq(void) ++{ ++ free_irq(the_card.irq_no, &the_card); ++ ps3_irq_plug_destroy(the_card.irq_no); ++} ++ ++static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) ++{ ++ uint64_t val; ++ int ret; ++ ++ val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) | ++ (0x03UL << 24) | ++ (0x0fUL << 12) | ++ (PS3_AUDIO_IOID); ++ ++ ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); ++ if (ret) ++ printk(KERN_ERR "%s: gpu_attribute failed %d\n", __func__, ++ ret); ++} ++ ++static int __init snd_ps3_driver_probe(struct ps3_system_bus_device * dev) ++{ ++ int ret; ++ u64 lpar_addr, lpar_size; ++ ++ BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); ++ BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND); ++ ++ the_card.ps3_dev = dev; ++ ++ ret = ps3_open_hv_device(dev); ++ ++ if (ret) ++ return -ENXIO; ++ ++ /* setup MMIO */ ++ ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size); ++ if (ret) { ++ printk(KERN_ERR "%s: device map 2 failed %d\n", __func__, ret); ++ goto clean_open; ++ } ++ ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size, ++ PAGE_SHIFT); ++ ++ if ((ret = snd_ps3_map_mmio())) { ++ goto clean_dev_map; ++ } ++ ++ /* setup DMA area */ ++ ps3_dma_region_init(dev, dev->d_region, ++ PAGE_SHIFT, /* use system page size */ ++ 0, /* dma type; not used */ ++ NULL, ++ _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE)); ++ dev->d_region->ioid = PS3_AUDIO_IOID; ++ ++ ret = ps3_dma_region_create(dev->d_region); ++ if (ret) { ++ printk("%s: region_create\n", __func__); ++ goto clean_mmio; ++ } ++ ++ snd_ps3_audio_set_base_addr(dev->d_region->bus_addr); ++ ++ /* CONFIG_SND_PS3_DEFAULT_START_DELAY */ ++ the_card.start_delay = snd_ps3_start_delay; ++ //the_card.platform_device = dev->dev; ++ ++ /* irq */ ++ if (snd_ps3_allocate_irq()) { ++ ret = -ENXIO; ++ goto clean_dma_region; ++ } ++ ++ /* create card instance */ ++ the_card.card = snd_card_new(index, id, THIS_MODULE, 0); ++ if (!the_card.card) { ++ ret = -ENXIO; ++ goto clean_irq; ++ } ++ ++ //snd_card_set_dev(the_card.card, &dev->core); ++ ++ strcpy(the_card.card->driver, "snd_ps3"); ++ strcpy(the_card.card->shortname, "PS3"); ++ strcpy(the_card.card->longname, "PS3 sound"); ++ /* create PCM devices instance */ ++ /* NOTE:this driver works assuming pcm:substream = 1:1 */ ++ ret = snd_pcm_new(the_card.card, ++ "SPDIF", ++ 0, /* instance index, will be stored pcm.device*/ ++ 1, /* output substream */ ++ 0, /* input substream */ ++ &(the_card.pcm)); ++ if (ret) ++ goto clean_card; ++ ++ the_card.pcm->private_data = &the_card; ++ strcpy(the_card.pcm->name, "SPDIF"); ++ ++ /* set pcm ops */ ++ snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_ps3_pcm_spdif_ops); ++ ++ the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED; ++ /* pre-alloc PCM DMA buffer*/ ++ ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm, ++ SNDRV_DMA_TYPE_DEV, ++ &dev->core, ++ SND_PS3_PCM_PREALLOC_SIZE, ++ SND_PS3_PCM_PREALLOC_SIZE); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: prealloc failed\n", __func__); ++ goto clean_card; ++ } ++ ++ /* ++ * allocate null buffer ++ * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 ++ * PAGE_SIZE is enogh ++ */ ++ if (!(the_card.null_buffer_start_vaddr = ++ dma_alloc_coherent(&the_card.ps3_dev->core, ++ PAGE_SIZE, ++ &the_card.null_buffer_start_dma_addr, ++ GFP_KERNEL))) { ++ printk(KERN_ERR "%s: nullbuffer alloc failed\n", __func__); ++ goto clean_preallocate; ++ } ++ pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, ++ the_card.null_buffer_start_vaddr, ++ the_card.null_buffer_start_dma_addr); ++ /* set default sample rate/word width */ ++ snd_ps3_init_avsetting(&the_card); ++ ++ /* add volume control */ ++ the_card.vol_control = snd_ctl_new1(&snd_ps3_vol_control, &the_card); ++ if ((ret = snd_ctl_add(the_card.card, the_card.vol_control)) < 0) { ++ goto clean_dma_map; ++ } ++ /* register the card */ ++ ret = snd_card_register(the_card.card); ++ if (ret < 0) ++ goto clean_ctl_add; ++ ++ //platform_set_drvdata(device, &the_card); ++ ++ printk("%s started. start_delay=%dms\n", ++ the_card.card->longname, the_card.start_delay); ++ return 0; ++ ++clean_ctl_add: ++ /* no need call to snd_control_free_one() here*/ ++ snd_ctl_remove(the_card.card, the_card.vol_control); ++clean_dma_map: ++ dma_free_coherent(&the_card.ps3_dev->core, ++ PAGE_SIZE, ++ the_card.null_buffer_start_vaddr, ++ the_card.null_buffer_start_dma_addr); ++clean_preallocate: ++ snd_pcm_lib_preallocate_free_for_all(the_card.pcm); ++clean_card: ++ snd_card_free(the_card.card); ++clean_irq: ++ snd_ps3_free_irq(); ++clean_dma_region: ++ ps3_dma_region_free(dev->d_region); ++clean_mmio: ++ snd_ps3_unmap_mmio(); ++clean_dev_map: ++ lv1_gpu_device_unmap(2); ++clean_open: ++ ps3_close_hv_device(dev); ++ /* ++ * there is no destructor function to pcm. ++ * midlayer automatically releases if the card removed ++ */ ++ return ret; ++}; /* snd_ps3_probe */ ++ ++/* called when module removal */ ++static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev) ++{ ++ int ret; ++ ++ if (dev->match_id != PS3_MATCH_ID_SOUND) ++ return -ENXIO; ++ ++ ret = snd_ctl_remove(the_card.card, the_card.vol_control); ++ if (ret) ++ printk("%s: ctl remove=%d\n", __func__,ret); ++ ret = snd_pcm_lib_preallocate_free_for_all(the_card.pcm); ++ if (ret) ++ printk("%s: ctl freepage=%d\n", __func__,ret); ++ ret = snd_card_free(the_card.card); ++ if (ret) ++ printk("%s: ctl freecard=%d\n", __func__,ret); ++ ++ dma_free_coherent(&dev->core, ++ PAGE_SIZE, ++ the_card.null_buffer_start_vaddr, ++ the_card.null_buffer_start_dma_addr); ++ ++ ps3_dma_region_free(dev->d_region); ++ ++ snd_ps3_free_irq(); ++ snd_ps3_unmap_mmio(); ++ ++ lv1_gpu_device_unmap(2); ++ ps3_close_hv_device(dev); ++ return 0; ++} /* snd_ps3_remove */ ++ ++static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { ++ .match_id = PS3_MATCH_ID_SOUND, ++ .probe = snd_ps3_driver_probe, ++ .remove = snd_ps3_driver_remove, ++ .shutdown = snd_ps3_driver_remove, ++ .core = { ++ .name = SND_PS3_DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++ ++/* ++ * Interrupt handler ++ */ ++static irqreturn_t snd_ps3_interrupt(int irq, void * dev_id) ++{ ++ ++ uint32_t port_intr; ++ int underflow_occured = 0; ++ struct snd_ps3_card_info * card = dev_id; ++ ++ if (!card->running) { ++ AUDIOREG(card, PS3_AUDIO_AX_IS) |= 0; ++ AUDIOREG(card, PS3_AUDIO_INTR_0) |= 0; ++ return IRQ_HANDLED; ++ } ++ ++ port_intr = AUDIOREG(card, PS3_AUDIO_AX_IS); ++ /* ++ *serial buffer empty detected (every 4 times), ++ *program next dma and kick it ++ */ ++ if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { ++ AUDIOREG(card, PS3_AUDIO_AX_IS) = PS3_AUDIO_AX_IE_ASOBEIE(0); ++ if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { ++ AUDIOREG(card, PS3_AUDIO_AX_IS) = port_intr; ++ underflow_occured = 1; ++ } ++ if (card->silent) { ++ /* we are still in silent time */ ++ snd_ps3_program_dma(card, ++ (underflow_occured) ? ++ SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : ++ SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); ++ snd_ps3_kick_dma(card); ++ card->silent --; ++ } else { ++ snd_ps3_program_dma(card, ++ (underflow_occured) ? ++ SND_PS3_DMA_FILLTYPE_FIRSTFILL : ++ SND_PS3_DMA_FILLTYPE_RUNNING); ++ snd_ps3_kick_dma(card); ++ snd_pcm_period_elapsed(card->substream); ++ } ++ } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { ++ AUDIOREG(card, PS3_AUDIO_AX_IS) = PS3_AUDIO_AX_IE_ASOBUIE(0); ++ /* ++ * serial out underflow, but buffer empty not detected. ++ * in this case, fill fifo with 0 to recover. After ++ * filling dummy data, serial automatically start to ++ * consume them and then will generate normal buffer ++ * empty interrupts. ++ * If both buffer underflow and buffer empty are occured, ++ * it is better to do nomal data transfer than empty one ++ */ ++ snd_ps3_program_dma(card, ++ SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); ++ snd_ps3_kick_dma(card); ++ snd_ps3_program_dma(card, ++ SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); ++ snd_ps3_kick_dma(card); ++ } ++ /* clear interrupt cause */ ++ return IRQ_HANDLED; ++}; ++ ++#ifdef _SND_PS3_DEV_ATTR ++/* ++ * sysfs ++ */ ++static ssize_t snd_ps3_get_start_delay(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct platform_device * plat_dev = ++ container_of(dev, struct platform_device, dev); ++ struct snd_ps3_card_info * card = platform_get_drvdata(plat_dev); ++ ssize_t ret; ++ ++ read_lock(&card->start_delay_lock); ++ ret = sprintf(buf, "%u\n", card->start_delay); ++ read_unlock(&card->start_delay_lock); ++ return ret; ++} ++ ++static ssize_t snd_ps3_set_start_delay(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ unsigned int start_delay; ++ struct platform_device * plat_dev = ++ container_of(dev, struct platform_device, dev); ++ struct snd_ps3_card_info * card = platform_get_drvdata(plat_dev); ++ ++ if (sscanf(buf, "%u", &start_delay) > 0) { ++ write_lock(&card->start_delay_lock); ++ card->start_delay = start_delay; ++ write_unlock(&card->start_delay_lock); ++ return strlen(buf); ++ } ++ return -EINVAL; ++} ++ ++#endif ++ ++static int snd_ps3_info_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_info * uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = SND_PS3_CH_MAX; /* stereo */ ++ uinfo->value.integer.min = SND_PS3_MIN_VOL; ++ uinfo->value.integer.max = SND_PS3_MAX_VOL; ++ return 0; ++}; ++ ++static int snd_ps3_get_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_value * ucontrol) ++{ ++ struct snd_ps3_card_info * card = snd_kcontrol_chip(kcontrol); ++ int i; ++ for (i = 0; i < SND_PS3_CH_MAX; i++) ++ ucontrol->value.integer.value[i] = ++ SND_PS3_MAX_VOL - card->attenuater[i]; ++ return 0; ++}; ++ ++static int snd_ps3_put_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_value * ucontrol) ++{ ++ struct snd_ps3_card_info * card = snd_kcontrol_chip(kcontrol); ++ int i; ++ int changed = 0; ++ ++ for (i = 0; i < SND_PS3_CH_MAX; i++) ++ if ((ucontrol->value.integer.value[i] < SND_PS3_MIN_VOL) || ++ (SND_PS3_MAX_VOL < ucontrol->value.integer.value[i])) ++ return -EINVAL; ++ ++ for (i = 0; i < SND_PS3_CH_MAX; i++) ++ if ((SND_PS3_MAX_VOL - card->attenuater[i]) != ++ ucontrol->value.integer.value[i]) { ++ card->attenuater[i] = SND_PS3_MAX_VOL - ++ ucontrol->value.integer.value[i]; ++ changed = 1; ++ } ++ return changed; ++}; ++ ++typedef struct ++{ ++ unsigned char numerator; ++ unsigned char denominator; ++} attenuater_divisor; ++ ++static const attenuater_divisor ++attenuater_divisor_array[SND_PS3_MAX_VOL - SND_PS3_MIN_VOL + 1] = ++{ ++ [ 0] = { 1, 1}, /* 0db; not used */ ++ [ 1] = { 177, 250}, /* -1.5 db 0.708 */ ++ [ 2] = { 1, 2}, /* -3.0 db 0.501 */ ++ [ 3] = { 71, 200}, /* -4.5 db 0.355 */ ++ [ 4] = { 1, 4}, /* -6.0 db 0.251 */ ++ [ 5] = { 45, 250}, /* -7.5 db 0.178 */ ++ [ 6] = { 1, 8}, /* -9.0 db 0.126 */ ++ [ 7] = { 22, 250}, /* -10.5 db 89.1m */ ++ [ 8] = { 1, 16}, /* -12.0 db 63.1m */ ++ [ 9] = { 11, 250}, /* -13.5 db 44.7m */ ++ [10] = { 1, 32}, /* -15.0 db 31.6m */ ++ [11] = { 5, 250}, /* -16.5 db 22.4m */ ++ [12] = { 1, 64}, /* -18.0 db 15.8m */ ++ [13] = { 2, 178}, /* -19.5 db 11.2m */ ++ [14] = { 1, 128}, /* -21.0 db 7.94m*/ ++ [15] = { 0, 1} /* mute; not used */ ++}; ++ ++/* ++ * software volume control ++ */ ++static void snd_ps3_do_attenuate_16(int attenuate, signed short int * start, ++ int samples) ++{ ++ int i; ++ ++ if (unlikely(attenuate == SND_PS3_MIN_ATT)) { ++ return; ++ } else if (attenuate == SND_PS3_MAX_ATT) { ++ memset(start, 0, sizeof(short int) * samples); ++ return; ++ } else { ++ for (i = 0; i < samples; i++) { ++ start[i] = start[i] * ++ attenuater_divisor_array[attenuate].numerator / ++ attenuater_divisor_array[attenuate].denominator; ++ } ++ } ++} ++ ++static void snd_ps3_do_attenuate_24(int attenuate, uint32_t * start, ++ int samples) ++{ ++ int i; ++ int32_t temp, temp2; ++ ++ if (unlikely(attenuate == SND_PS3_MIN_ATT)) { ++ return; ++ } else if (attenuate == SND_PS3_MAX_ATT) { ++ memset(start, 0, sizeof(uint32_t) * samples); ++ return; ++ } else { ++ for (i = 0; i < samples; i++) { ++ /* 24bit -> 32bit */ ++ temp = (int32_t)(start[i] << 8); ++ /* shift alithmetic */ ++ temp2 = temp >> 8; ++ /* ++ * Since upper 8 bits will be disposed of by the ++ * hardware, leave it untouched. ++ */ ++ start[i] = temp2 * ++ attenuater_divisor_array[attenuate].numerator / ++ attenuater_divisor_array[attenuate].denominator; ++ } ++ } ++} ++ ++static int snd_ps3_soft_attenuate(struct snd_ps3_card_info *card, ++ void * start_l, void * start_r, int bytes) ++{ ++ ++ switch(snd_pcm_format_width(card->substream->runtime->format)) { ++ case 16: ++ snd_ps3_do_attenuate_16(card->attenuater[SND_PS3_CH_L], ++ start_l, bytes / 2); ++ snd_ps3_do_attenuate_16(card->attenuater[SND_PS3_CH_R], ++ start_r, bytes / 2); ++ break; ++ case 24: ++ snd_ps3_do_attenuate_24(card->attenuater[SND_PS3_CH_L], ++ start_l, bytes / 4); ++ snd_ps3_do_attenuate_24(card->attenuater[SND_PS3_CH_R], ++ start_r, bytes / 4); ++ break; ++ default: ++ printk(KERN_ERR "%s: invalid width %d\n", __func__, ++ snd_pcm_format_width(card->substream->runtime->format)); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++/* ++ * module/subsystem initialize/terminate ++ */ ++static int __init snd_ps3_init(void) ++{ ++ int ret; ++ ++ if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) ++ return -ENXIO; ++ ++ memset(&the_card, 0, sizeof(the_card)); ++ rwlock_init(&the_card.dma_lock); ++ rwlock_init(&the_card.start_delay_lock); ++ ++ /* register systembus DRIVER, this calls our probe() func */ ++ ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info); ++ ++ return ret; ++} ++ ++static void __exit snd_ps3_exit(void) ++{ ++ pr_debug("%s:start\n", __func__); ++ ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); ++ pr_debug("%s:end\n", __func__); ++} ++ ++MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); +--- /dev/null ++++ b/sound/ppc/snd_ps3.h +@@ -0,0 +1,207 @@ ++/* ++ * Audio support for PS3 ++ * Copyright (C) 2006 Sony Computer Entertainment Inc. ++ * All rights reserved. ++ * Copyright 2006, 2007 Sony Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; version 2 of the Licence. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#if !defined(_SND_PS3_H_) ++#define _SND_PS3_H_ ++ ++#include ++ ++#define SND_PS3_DRIVER_NAME "snd_ps3" ++ ++enum snd_ps3_out_channel { ++ SND_PS3_OUT_SPDIF_0, ++ SND_PS3_OUT_SPDIF_1, ++ SND_PS3_OUT_SERIAL_0, ++ SND_PS3_OUT_DEVS ++}; ++ ++enum snd_ps3_dma_filltype { ++ SND_PS3_DMA_FILLTYPE_FIRSTFILL, ++ SND_PS3_DMA_FILLTYPE_RUNNING, ++ SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL, ++ SND_PS3_DMA_FILLTYPE_SILENT_RUNNING ++}; ++ ++enum snd_ps3_ch { ++ SND_PS3_CH_L = 0, ++ SND_PS3_CH_R = 1, ++ SND_PS3_CH_MAX = 2 ++}; ++ ++struct snd_ps3_avsetting_info { ++ uint32_t avs_audio_ch; /* fixed */ ++ uint32_t avs_audio_rate; ++ uint32_t avs_audio_width; ++ uint32_t avs_audio_format; /* fixed */ ++ uint32_t avs_audio_source; /* fixed */ ++}; ++/* ++ * PS3 audio 'card' instance ++ * there should be only ONE hardware. ++ */ ++struct snd_ps3_card_info { ++ struct ps3_system_bus_device * ps3_dev; ++ //struct platform_device * platform_device; ++ struct snd_card * card; ++ ++ struct snd_pcm * pcm; ++ struct snd_pcm_substream * substream; ++ ++ /* hvc info */ ++ u64 audio_lpar_addr; ++ u64 audio_lpar_size; ++ ++ /* registers */ ++ void * mapped_mmio_vaddr; ++ ++ /* irq */ ++ u64 audio_irq_outlet; ++ unsigned int irq_no; ++ ++ /* remember avsetting */ ++ struct snd_ps3_avsetting_info avs; ++ ++ /* dma buffer management */ ++ rwlock_t dma_lock; ++ /* dma_lock start */ ++ void * dma_start_vaddr[2]; /* 0 for L, 1 for R */ ++ dma_addr_t dma_start_bus_addr[2]; ++ size_t dma_buffer_size; ++ void * dma_last_transfer_vaddr[2]; ++ void * dma_next_transfer_vaddr[2]; ++ int silent; ++ /* dma_lock end */ ++ ++ int running; ++ ++ /* null buffer */ ++ void * null_buffer_start_vaddr; ++ dma_addr_t null_buffer_start_dma_addr; ++ ++ /* start delay */ ++ rwlock_t start_delay_lock; ++ /* start_delay_lock start */ ++ unsigned int start_delay; ++ /* start_delay_lock end */ ++ ++ struct snd_kcontrol * vol_control; ++ int attenuater[2]; /* store by attenuation, not volume*/ ++}; ++ ++ ++/* module entries */ ++static int __init snd_ps3_init(void); ++static void __exit snd_ps3_exit(void); ++ ++/* ALSA snd driver ops */ ++static int snd_ps3_pcm_open(struct snd_pcm_substream * substream); ++static int snd_ps3_pcm_close(struct snd_pcm_substream * substream); ++static int snd_ps3_pcm_prepare(struct snd_pcm_substream * substream); ++static int snd_ps3_pcm_trigger(struct snd_pcm_substream * substream, ++ int cmd); ++static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream * ++ substream); ++static int snd_ps3_pcm_hw_params(struct snd_pcm_substream * substream, ++ struct snd_pcm_hw_params * hw_params); ++static int snd_ps3_pcm_hw_free(struct snd_pcm_substream * substream); ++ ++ ++/* ps3_system_bus_driver entries */ ++static int __init snd_ps3_driver_probe(struct ps3_system_bus_device * dev); ++//static void snd_ps3_driver_shutdown(struct ps3_system_bus_device * dev); ++static int snd_ps3_driver_remove(struct ps3_system_bus_device * dev); ++ ++/* address setup */ ++static int snd_ps3_map_mmio(void); ++static void snd_ps3_unmap_mmio(void); ++static int snd_ps3_allocate_irq(void); ++static void snd_ps3_free_irq(void); ++static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); ++ ++/* interrupt handler */ ++static irqreturn_t snd_ps3_interrupt(int irq, void * dev_id); ++ ++ ++/* set sampling rate/format */ ++static int snd_ps3_set_avsetting(struct snd_pcm_substream * substream); ++/* take effect parameter change */ ++static int snd_ps3_change_avsetting(struct snd_ps3_card_info * card); ++/* initialize avsetting and take it effect */ ++static int snd_ps3_init_avsetting(struct snd_ps3_card_info * card); ++/* setup dma */ ++static int snd_ps3_program_dma(struct snd_ps3_card_info * card, ++ enum snd_ps3_dma_filltype filltype); ++//static int snd_ps3_kick_dma(struct snd_ps3_card_info * card); ++static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info * card); ++ ++static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void * vaddr, int ch); ++ ++#ifdef _SND_PS3_DEV_ATTR ++static ssize_t snd_ps3_get_start_delay(struct device *dev, ++ struct device_attribute *attr, ++ char *buf); ++static ssize_t snd_ps3_set_start_delay(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count); ++#endif ++ ++static int snd_ps3_info_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_info * uinfo); ++static int snd_ps3_get_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_value * ucontrol); ++static int snd_ps3_put_vol_control(struct snd_kcontrol * kcontrol, ++ struct snd_ctl_elem_value * ucontrol); ++ ++static int snd_ps3_soft_attenuate(struct snd_ps3_card_info * card, ++ void * start_l, void * star_r, int bytes); ++ ++/* PS3 audio DMAC block size in bytes */ ++#define PS3_AUDIO_DMAC_BLOCK_SIZE (128) ++/* one stage (stereo) of audio FIFO in bytes */ ++#define PS3_AUDIO_FIFO_STAGE_SIZE (256) ++/* how many stages the fifo have */ ++#define PS3_AUDIO_FIFO_STAGE_COUNT (8) ++/* fifo size 128 bytes * 8 stages * stereo (2ch) */ ++#define PS3_AUDIO_FIFO_SIZE \ ++ (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT) ++ ++/* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/ ++#define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1) ++ ++#define PS3_AUDIO_NORMAL_DMA_START_CH (0) ++#define PS3_AUDIO_NORMAL_DMA_COUNT (8) ++#define PS3_AUDIO_NULL_DMA_START_CH \ ++ (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT) ++#define PS3_AUDIO_NULL_DMA_COUNT (2) ++ ++#define SND_PS3_MAX_VOL (0x0F) ++#define SND_PS3_MIN_VOL (0x00) ++#define SND_PS3_MIN_ATT SND_PS3_MIN_VOL ++#define SND_PS3_MAX_ATT SND_PS3_MAX_VOL ++ ++#define SND_PS3_PCM_PREALLOC_SIZE \ ++ (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4) ++ ++#define SND_PS3_DMA_REGION_SIZE \ ++ (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE) ++ ++#define PS3_AUDIO_IOID (1UL) ++ ++#endif /* _SND_PS3_H_ */ +--- /dev/null ++++ b/sound/ppc/snd_ps3_reg.h +@@ -0,0 +1,856 @@ ++/* ++ * Audio support for PS3 ++ * Copyright (C) 2006 Sony Computer Entertainment Inc. ++ * Copyright 2006, 2007 Sony Corporation ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * interrupt / configure registers ++ */ ++ ++#define PS3_AUDIO_INTR_0 (0x00000100) ++#define PS3_AUDIO_INTR_EN_0 (0x00000140) ++#define PS3_AUDIO_CONFIG (0x00000200) ++ ++/* ++ * DMAC registers ++ * n:0..9 ++ */ ++#define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x)) ++ ++#define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00) ++#define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04) ++#define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08) ++#define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C) ++ ++/* ++ * mute control ++ */ ++#define PS3_AUDIO_AX_MCTRL (0x00004000) ++#define PS3_AUDIO_AX_ISBP (0x00004004) ++#define PS3_AUDIO_AX_AOBP (0x00004008) ++#define PS3_AUDIO_AX_IC (0x00004010) ++#define PS3_AUDIO_AX_IE (0x00004014) ++#define PS3_AUDIO_AX_IS (0x00004018) ++ ++/* ++ * three wire serial ++ * n:0..3 ++ */ ++#define PS3_AUDIO_AO_MCTRL (0x00006000) ++#define PS3_AUDIO_AO_3WMCTRL (0x00006004) ++ ++#define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n)) ++ ++/* ++ * S/PDIF ++ * n:0..1 ++ * x:0..11 ++ * y:0..5 ++ */ ++#define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n)) ++ ++#define PS3_AUDIO_AO_SPDCTRL(n) (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00) ++#define PS3_AUDIO_AO_SPDUB(n,x) (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x)) ++#define PS3_AUDIO_AO_SPDCS(n,y) (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y)) ++ ++ ++/* ++ PS3_AUDIO_INTR_0 register tells an interrupt handler which audio ++ DMA channel triggered the interrupt. The interrupt status for a channel ++ can be cleared by writing a '1' to the corresponding bit. A new interrupt ++ cannot be generated until the previous interrupt has been cleared. ++ ++ Note that the status reported by PS3_AUDIO_INTR_0 is independent of the ++ value of PS3_AUDIO_INTR_EN_0. ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++#define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2)) ++#define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9) ++#define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8) ++#define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7) ++#define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6) ++#define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5) ++#define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4) ++#define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3) ++#define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2) ++#define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1) ++#define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0) ++ ++/* ++ The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate ++ an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the ++ corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together ++ to generate the Audio interrupt. ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++ Bit assignments are same as PS3_AUDIO_INTR_0 ++*/ ++ ++/* ++ PS3_AUDIO_CONFIG ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++*/ ++ ++/* The CLEAR field cancels all pending transfers, and stops any running DMA ++ transfers. Any interrupts associated with the canceled transfers ++ will occur as if the transfer had finished. ++ Since this bit is designed to recover from DMA related issues ++ which are caused by unpredictable situations, it is prefered to wait ++ for normal DMA transfer end without using this bit. ++*/ ++#define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */ ++ ++/* ++ PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++/* 3 Wire Audio Serial Output Channel Mutes (0..3) */ ++#define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */ ++ ++/* S/PDIF mutes (0,1)*/ ++#define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */ ++#define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */ ++ ++/* All 3 Wire Serial Outputs Mute */ ++#define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */ ++ ++/* All S/PDIF Mute */ ++#define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */ ++ ++/* All Audio Outputs Mute */ ++#define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */ ++ ++/* ++ S/PDIF Outputs Buffer Read/Write Pointer Register ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++*/ ++/* ++ S/PDIF Output Channel Read Buffer Numbers ++ Buffer number is value of field. ++ Indicates current read access buffer ID from Audio Data ++ Transfer controller of S/PDIF Output ++*/ ++ ++#define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */ ++#define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */ ++#define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */ ++ ++/* ++S/PDIF Output Channel Buffer Write Numbers ++Indicates current write access buffer ID from bus master. ++*/ ++#define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */ ++#define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */ ++#define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */ ++ ++/* ++ 3 Wire Audio Serial Outputs Buffer Read/Write ++ Pointer Register ++ Buffer number is value of field ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++/* ++3 Wire Audio Serial Output Channel Buffer Read Numbers ++Indicates current read access buffer Id from Audio Data Transfer ++Controller of 3 Wire Audio Serial Output Channels ++*/ ++#define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */ ++ ++#define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */ ++ ++/* ++3 Wire Audio Serial Output Channel Buffer Write Numbers ++Indicates current write access buffer ID from bus master. ++*/ ++#define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */ ++ ++#define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */ ++#define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */ ++ ++ ++ ++/* ++Audio Port Interrupt Condition Register ++For the fields in this register, the following values apply: ++0 = Interrupt is generated every interrupt event. ++1 = Interrupt is generated every 2 interrupt events. ++2 = Interrupt is generated every 4 interrupt events. ++3 = Reserved ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++/* ++All 3-Wire Audio Serial Outputs Interrupt Mode ++Configures the Interrupt and Signal Notification ++condition of all 3-wire Audio Serial Outputs. ++*/ ++#define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */ ++#define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */ ++#define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */ ++#define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */ ++ ++/* ++S/PDIF Output Channel Interrupt Modes ++Configures the Interrupt and signal Notification ++conditions of S/PDIF output channels. ++*/ ++#define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */ ++#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */ ++#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */ ++#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */ ++ ++#define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */ ++#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */ ++#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */ ++#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */ ++ ++/* ++Audio Port interrupt Enable Register ++Configures whether to enable or disable each Interrupt Generation. ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++*/ ++ ++/* ++3 Wire Audio Serial Output Channel Buffer Underflow ++Interrupt Enables ++Select enable/disable of Buffer Underflow Interrupts for ++3-Wire Audio Serial Output Channels ++DISABLED=Interrupt generation disabled. ++*/ ++#define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */ ++ ++/* S/PDIF Output Channel Buffer Underflow Interrupt Enables */ ++ ++#define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */ ++ ++/* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */ ++ ++#define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */ ++ ++/* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */ ++ ++#define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */ ++ ++/* S/PDIF Output Channel Buffer Empty Interrupt Enables */ ++ ++#define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */ ++#define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */ ++ ++/* ++Audio Port Interrupt Status Register ++Indicates Interrupt status, which interrupt has occured, and can clear ++each interrupt in this register. ++Writing 1b to a field containing 1b clears field and de-asserts interrupt. ++Writing 0b to a field has no effect. ++Field vaules are the following: ++0 - Interrupt hasn't occured. ++1 - Interrupt has occured. ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++ Bit assignment are same as AX_IE ++*/ ++ ++/* ++Audio Output Master Control Register ++Configures Master Clock and other master Audio Output Settings ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++/* ++MCLK Output Control ++Controls mclko[1] output. ++0 - Disable output (fixed at High) ++1 - Output clock produced by clock selected ++with scksel1 by mr1 ++2 - Reserved ++3 - Reserved ++*/ ++ ++#define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */ ++ ++/* ++MCLK Output Control ++Controls mclko[0] output. ++0 - Disable output (fixed at High) ++1 - Output clock produced by clock selected ++with SCKSEL0 by MR0 ++2 - Reserved ++3 - Reserved ++*/ ++#define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */ ++#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */ ++/* ++Master Clock Rate 1 ++Sets the divide ration of Master Clock1 (clock output from ++mclko[1] for the input clock selected by scksel1. ++*/ ++#define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16) ++#define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */ ++/* ++Master Clock Rate 0 ++Sets the divide ratio of Master Clock0 (clock output from ++mclko[0] for the input clock selected by scksel0). ++*/ ++#define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */ ++#define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */ ++/* ++System Clock Select 0/1 ++Selects the system clock to be used as Master Clock 0/1 ++Input the system clock that is appropriate for the sampling ++rate. ++*/ ++#define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */ ++#define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */ ++ ++#define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */ ++#define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */ ++ ++ ++/* ++3-Wire Audio Output Master Control Register ++Configures clock, 3-Wire Audio Serial Output Enable, and ++other 3-Wire Audio Serial Output Master Settings ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++ ++/* ++LRCKO Polarity ++0 - Reserved ++1 - default ++*/ ++#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */ ++ ++/* LRCK Output Disable */ ++ ++#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */ ++ ++/* Bit Clock Output Disable */ ++ ++#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */ ++ ++/* ++3-Wire Audio Serial Output Channel 0-3 Operational ++Status. Each bit becomes 1 after each 3-Wire Audio ++Serial Output Channel N is in action by setting 1 to ++asoen. ++Each bit becomes 0 after each 3-Wire Audio Serial Output ++Channel N is out of action by setting 0 to asoen. ++*/ ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN0 PS3_AUDIO_AO_3WMCTRL_ASORUN(0) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN1 PS3_AUDIO_AO_3WMCTRL_ASORUN(1) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN2 PS3_AUDIO_AO_3WMCTRL_ASORUN(2) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN3 PS3_AUDIO_AO_3WMCTRL_ASORUN(3) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3) ++#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3) ++ ++/* ++Sampling Rate ++Specifies the divide ratio of the bit clock (clock output ++from bclko) used by the 3-wire Audio Output Clock, whcih ++is applied to the master clock selected by mcksel. ++Data output is synchronized with this clock. ++*/ ++#define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */ ++ ++/* ++Master Clock Select ++0 - Master Clock 0 ++1 - Master Clock 1 ++*/ ++#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */ ++ ++/* ++Enables and disables 4ch 3-Wire Audio Serial Output ++operation. Each Bit from 0 to 3 corresponds to an ++output channel, which means that each output channel ++can be enabled or disabled individually. When ++multiple channels are enabled at the same time, output ++operations are performed in synchronization. ++Bit 0 - Output Channel 0 (SDOUT[0]) ++Bit 1 - Output Channel 1 (SDOUT[1]) ++Bit 2 - Output Channel 2 (SDOUT[2]) ++Bit 3 - Output Channel 3 (SDOUT[3]) ++*/ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */ ++ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN0 PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */ ++#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */ ++#define PS3_AUDIO_A1_3WMCTRL_ASOEN0 PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */ ++#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */ ++#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */ ++#define PS3_AUDIO_A2_3WMCTRL_ASOEN0 PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */ ++#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */ ++#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */ ++#define PS3_AUDIO_A3_3WMCTRL_ASOEN0 PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */ ++#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */ ++#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */ ++ ++/* ++3-Wire Audio Serial output Channel 0-3 Control Register ++Configures settings for 3-Wire Serial Audio Output Channel 0-3 ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++*/ ++/* ++Data Bit Mode ++Specifies the number of data bits ++0 - 16 bits ++1 - reserved ++2 - 20 bits ++3 - 24 bits ++*/ ++#define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */ ++#define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */ ++#define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */ ++#define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */ ++#define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */ ++/* ++Data Format Mode ++Specifies the data format where (LSB side or MSB) the data(in 20 bit ++or 24 bit resolution mode) is put in a 32 bit field. ++0 - Data put on LSB side ++1 - Data put on MSB side ++*/ ++#define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */ ++#define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */ ++#define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */ ++/* ++Buffer Reset ++Performs buffer reset. Writing 1 to this bit initializes the ++corresponding 3-Wire Audio Output buffers(both L and R). ++*/ ++#define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */ ++#define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */ ++#define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */ ++ ++/* ++S/PDIF Audio Output Channel 0/1 Control Register ++Configures settings for S/PDIF Audio Output Channel 0/1. ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++/* ++Buffer reset. Writing 1 to this bit initializes the ++corresponding S/PDIF output buffer pointer. ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */ ++ ++/* ++Data Bit Mode ++Specifies number of data bits ++0 - 16 bits ++1 - Reserved ++2 - 20 bits ++3 - 24 bits ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */ ++/* ++Data format Mode ++Specifies the data format, where (LSB side or MSB) ++the data(in 20 or 24 bit resolution) is put in the ++32 bit field. ++0 - LSB Side ++1 - MSB Side ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */ ++/* ++Source Select ++Specifies the source of the S/PDIF output. When 0, output ++operation is controlled by 3wen[0] of AO_3WMCTRL register. ++The SR must have the same setting as the a0_3wmctrl reg. ++0 - 3-Wire Audio OUT Ch0 Buffer ++1 - S/PDIF buffer ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */ ++/* ++Sampling Rate ++Specifies the divide ratio of the bit clock (clock output ++from bclko) used by the S/PDIF Output Clock, which ++is applied to the master clock selected by mcksel. ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */ ++/* ++Master Clock Select ++0 - Master Clock 0 ++1 - Master Clock 1 ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */ ++ ++/* ++S/PDIF Output Channel Operational Status ++This bit becomes 1 after S/PDIF Output Channel is in ++action by setting 1 to spoen. This bit becomes 0 ++after S/PDIF Output Channel is out of action by setting ++0 to spoen. ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */ ++ ++/* ++S/PDIF Audio Output Channel Output Enable ++Enables and disables output operation. This bit is used ++only when sposs = 1 ++*/ ++#define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */ ++#define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */ ++ ++/* ++S/PDIF Audio Output Channel Channel Status ++Setting Registers. ++Configures channel status bit settings for each block ++(192 bits). ++Output is performed from the MSB(AO_SPDCS0 register bit 31). ++The same value is added for subframes within the same frame. ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ | SPOCS | AO_SPDCS ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ ++S/PDIF Audio Output Channel User Bit Setting ++Configures user bit settings for each block (384 bits). ++Output is performed from the MSB(ao_spdub0 register bit 31). ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ | SPOUB | AO_SPDUB ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++/******************************************************************************* ++ * ++ * DMAC register ++ * ++ *******************************************************************************/ ++/* ++The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor its status ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++/* ++The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT occurs. ++It will return to the DONE state when the request is completed. ++The registers for a DMA channel should only be written if REQUEST is IDLE. ++*/ ++ ++#define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */ ++#define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */ ++#define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */ ++ ++/* The EVENT field is used to set the event in which the DMA request becomes active. */ ++#define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */ ++#define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE (0x09 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE (0x0C << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */ ++ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) ((0x13 + (n)) << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */ ++#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */ ++ ++/* ++The STATUS field can be used to monitor the progress of a DMA request. ++DONE indicates the previous request has completed. ++EVENT indicates that the DMA engine is waiting for the EVENT to occur. ++PENDING indicates that the DMA engine has not started processing this ++request, but the EVENT has occured. ++DMA indicates that the data transfer is in progress. ++NOTIFY indicates that the notifier signalling end of transfer is being written. ++CLEAR indicated that the previous transfer was cleared. ++ERROR indicates the previous transfer requested an unsupported source/destination combination. ++*/ ++ ++#define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */ ++#define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */ ++#define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */ ++#define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */ ++#define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */ ++#define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */ ++#define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */ ++#define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */ ++ ++/* ++The PS3_AUDIO_SOURCE register specifies the source address for transfers. ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ | START |0 0 0 0 0|TAR| SOURCE ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++/* ++The Audio DMA engine uses 128-byte transfers, thus the address must be aligned ++to a 128 byte boundary. The low seven bits are assumed to be 0. ++*/ ++ ++#define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */ ++ ++/* ++The TARGET field specifies the memory space containing the source address. ++*/ ++ ++#define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */ ++#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */ ++ ++/* ++The PS3_AUDIO_DEST register specifies the destination address for transfers. ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ | START |0 0 0 0 0|TAR| DEST ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++/* ++The Audio DMA engine uses 128-byte transfers, thus the address must be aligned ++to a 128 byte boundary. The low seven bits are assumed to be 0. ++*/ ++ ++#define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */ ++ ++/* ++The TARGET field specifies the memory space containing the destination address ++AUDIOFIFO = Audio WriteData FIFO, ++*/ ++ ++#define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */ ++#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */ ++ ++/* ++PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer. ++So a value of 0 means 128-bytes will get transfered. ++ ++ ++ 31 24 23 16 15 8 7 0 ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++ |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE ++ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ ++*/ ++ ++ ++#define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */ ++ ++/* ++ * source/destination address for internal fifos ++ */ ++#define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n))) ++#define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n))) ++ ++#define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n))) ++ ++ ++/************************************************************************ ++ field attiribute ++ ++ Read ++ ' ' = Other Information ++ '-' = Field is part of a write-only register ++ 'C' = Value read is always the same, constant value line follows (C) ++ 'R' = Value is read ++ ++ Write ++ ' ' = Other Information ++ '-' = Must not be written (D), value ignored when written (R,A,F) ++ 'W' = Can be written ++ ++ Internal State ++ ' ' = Other Information ++ '-' = No internal state ++ 'X' = Internal state, initial value is unknown ++ 'I' = Internal state, initial value is known and follows (I) ++ ++ Declaration/Size ++ ' ' = Other Information ++ '-' = Does Not Apply ++ 'V' = Type is void ++ 'U' = Type is unsigned integer ++ 'S' = Type is signed integer ++ 'F' = Type is IEEE floating point ++ '1' = Byte size (008) ++ '2' = Short size (016) ++ '3' = Three byte size (024) ++ '4' = Word size (032) ++ '8' = Double size (064) ++ ++ Define Indicator ++ ' ' = Other Information ++ 'D' = Device ++ 'M' = Memory ++ 'R' = Register ++ 'A' = Array of Registers ++ 'F' = Field ++ 'V' = Value ++ 'T' = Task ++ ++ **********************************************************************/ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/51-ps3-bt-event-filter.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/51-ps3-bt-event-filter.patch @@ -0,0 +1,68 @@ +Subject: PS3 Bluetooth quirk for HCI_FLT_CLEAR_ALL + +This patch is still WIP. + +It seems the PS3 built-in bluetooth host controler doesn't support the +HCI_FLT_CLEAR_ALL command properly. Add a check to conditionally use +the HCI_FLT_CONN_SETUP command to clear the event filter on PS3. + +With this patch bluetooth mouse or keyboard are automatically re-connected +after reboot. + +Signed-off-by: Geoff Levand + +--- + include/net/bluetooth/hci.h | 6 ++++++ + net/bluetooth/hci_core.c | 19 +++++++++++++++++++ + 2 files changed, 25 insertions(+) + +--- ps3-linux-dev.orig/include/net/bluetooth/hci.h ++++ ps3-linux-dev/include/net/bluetooth/hci.h +@@ -251,6 +251,12 @@ struct hci_cp_set_event_flt { + __u8 condition[0]; + } __attribute__ ((packed)); + ++struct hci_cp_set_event_flt_conn { ++ __u8 flt_type; ++ __u8 cond_type; ++ __u8 condition; ++} __attribute__ ((packed)); ++ + /* Filter types */ + #define HCI_FLT_CLEAR_ALL 0x00 + #define HCI_FLT_INQ_RESULT 0x01 +--- ps3-linux-dev.orig/net/bluetooth/hci_core.c ++++ ps3-linux-dev/net/bluetooth/hci_core.c +@@ -46,6 +46,9 @@ + + #include + #include ++#if defined(CONFIG_PPC_PS3) ++#include ++#endif + + #ifndef CONFIG_BT_HCI_CORE_DEBUG + #undef BT_DBG +@@ -239,6 +242,22 @@ static void hci_init_req(struct hci_dev + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, sizeof(cp), &cp); + } + ++#if defined(CONFIG_PPC_PS3) ++ /* ++ * The PS3 built-in bluetooth host controler doesn't support the ++ * HCI_FLT_CLEAR_ALL command properly. Use the HCI_FLT_CONN_SETUP ++ * command to clear the event filter. ++ */ ++ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { ++ struct hci_cp_set_event_flt_conn cp; ++ cp.flt_type = HCI_FLT_CONN_SETUP; ++ cp.cond_type = 0; /* all devices */ ++ cp.condition = 1; /* auto accept is off */ ++ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, sizeof(cp), ++ &cp); ++ } ++#endif ++ + /* Page timeout ~20 secs */ + param = cpu_to_le16(0x8000); + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, ¶m); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/04-ps3-use-ioremap-flags.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/04-ps3-use-ioremap-flags.patch @@ -0,0 +1,71 @@ +Subject: PS3: Use ioremap_flags + +Use ioremap_flags() to map SPU regions as non-guarded. +Change the use of _ioremap() to ioremap_flags(). + +CC: Arnd Bergmann +CC: Masato Noguchi +CC: Takao Shinohara +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/htab.c | 2 +- + arch/powerpc/platforms/ps3/spu.c | 19 ++++++++++++------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +--- a/arch/powerpc/platforms/ps3/htab.c ++++ b/arch/powerpc/platforms/ps3/htab.c +@@ -273,7 +273,7 @@ void __init ps3_map_htab(void) + + result = lv1_map_htab(0, &htab_addr); + +- htab = (hpte_t *)__ioremap(htab_addr, htab_size, ++ htab = (hpte_t *)ioremap_flags(htab_addr, htab_size, + pgprot_val(PAGE_READONLY_X)); + + DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, +--- a/arch/powerpc/platforms/ps3/spu.c ++++ b/arch/powerpc/platforms/ps3/spu.c +@@ -182,30 +182,35 @@ static int __init setup_areas(struct spu + { + struct table {char* name; unsigned long addr; unsigned long size;}; + +- spu_pdata(spu)->shadow = __ioremap( ++ spu_pdata(spu)->shadow = (__force void *)ioremap_flags( + spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), +- pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED); ++ pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE); ++ + if (!spu_pdata(spu)->shadow) { + pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); + goto fail_ioremap; + } + +- spu->local_store = ioremap(spu->local_store_phys, LS_SIZE); ++ spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys, ++ LS_SIZE, _PAGE_NO_CACHE); ++ + if (!spu->local_store) { + pr_debug("%s:%d: ioremap local_store failed\n", + __func__, __LINE__); + goto fail_ioremap; + } + +- spu->problem = ioremap(spu->problem_phys, +- sizeof(struct spu_problem)); ++ spu->problem = (__force void *)ioremap_flags(spu->problem_phys, ++ sizeof(struct spu_problem), _PAGE_NO_CACHE); ++ + if (!spu->problem) { + pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); + goto fail_ioremap; + } + +- spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, +- sizeof(struct spu_priv2)); ++ spu->priv2 = (__force void *)ioremap_flags(spu_pdata(spu)->priv2_addr, ++ sizeof(struct spu_priv2), _PAGE_NO_CACHE); ++ + if (!spu->priv2) { + pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); + goto fail_ioremap; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/23-ps3-use-clear_bit.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/23-ps3-use-clear_bit.patch @@ -0,0 +1,66 @@ +Subject: PS3: System-bus rework +CC: michael@ellerman.id.au +CC: Benjamin Herrenschmidt + +Replace inline asm to bitops routines in the PS3 interrupt +chip mask routines. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/interrupt.c | 26 ++------------------------ + 1 file changed, 2 insertions(+), 24 deletions(-) + +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -100,24 +100,13 @@ static DEFINE_PER_CPU(struct ps3_private + static void ps3_chip_mask(unsigned int virq) + { + struct ps3_private *pd = get_irq_chip_data(virq); +- u64 bit = 0x8000000000000000UL >> virq; +- u64 *p = &pd->bmp.mask; +- u64 old; + unsigned long flags; + + pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, + pd->thread_id, virq); + + local_irq_save(flags); +- asm volatile( +- "1: ldarx %0,0,%3\n" +- "andc %0,%0,%2\n" +- "stdcx. %0,0,%3\n" +- "bne- 1b" +- : "=&r" (old), "+m" (*p) +- : "r" (bit), "r" (p) +- : "cc" ); +- ++ clear_bit(63 - virq, &pd->bmp.mask); + lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); + local_irq_restore(flags); + } +@@ -132,24 +121,13 @@ static void ps3_chip_mask(unsigned int v + static void ps3_chip_unmask(unsigned int virq) + { + struct ps3_private *pd = get_irq_chip_data(virq); +- u64 bit = 0x8000000000000000UL >> virq; +- u64 *p = &pd->bmp.mask; +- u64 old; + unsigned long flags; + + pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, + pd->thread_id, virq); + + local_irq_save(flags); +- asm volatile( +- "1: ldarx %0,0,%3\n" +- "or %0,%0,%2\n" +- "stdcx. %0,0,%3\n" +- "bne- 1b" +- : "=&r" (old), "+m" (*p) +- : "r" (bit), "r" (p) +- : "cc" ); +- ++ set_bit(63 - virq, &pd->bmp.mask); + lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); + local_irq_restore(flags); + } --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/05-ps3-sparse-warnings.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/05-ps3-sparse-warnings.patch @@ -0,0 +1,33 @@ +Subject: PS3: Fix sparse warnings +From: Geert Uytterhoeven + +Fix some PS3 build warnings reported by `make C=1'. You need to +install sparse: + git://git.kernel.org/pub/scm/devel/sparse/sparse.git + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/os-area.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/platforms/ps3/os-area.c ++++ b/arch/powerpc/platforms/ps3/os-area.c +@@ -133,7 +133,7 @@ struct saved_params { + } static saved_params; + + #define dump_header(_a) _dump_header(_a, __func__, __LINE__) +-static void _dump_header(const struct os_area_header __iomem *h, const char* func, ++static void _dump_header(const struct os_area_header *h, const char* func, + int line) + { + pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, +@@ -151,7 +151,7 @@ static void _dump_header(const struct os + } + + #define dump_params(_a) _dump_params(_a, __func__, __LINE__) +-static void _dump_params(const struct os_area_params __iomem *p, const char* func, ++static void _dump_params(const struct os_area_params *p, const char* func, + int line) + { + pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/18-ps3-system-bus-rework-sys-manager.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/18-ps3-system-bus-rework-sys-manager.patch @@ -0,0 +1,661 @@ +Subject: PS3: System manager re-work + +PS3 sys-manager updates to reflect the new PS3 unifed device support. +Fixups to the PS3 sys-manager driver to properly support sys_reboot(). + - Add varable request_tag to struct ps3_sys_manager_header. + - Move ctrl_alt_del from PS3_SM_EVENT_POWER_RELEASED to + PS3_SM_EVENT_POWER_PRESSED. + - Make the PS3 sys-manager driver a loadable module. + - Add new file sys-manager-core.c. + - Add new struct ps3_sys_manager_ops for dynamic binding. + - Put data sent to device on stack. + - Add support for PS3_SM_SERVICE_ID_REQUEST_ERROR. + +Signed-off-by: Geoff Levand +--- + drivers/ps3/Makefile | 1 + drivers/ps3/sys-manager-core.c | 68 +++++++++ + drivers/ps3/sys-manager.c | 280 ++++++++++++++++++++++++++--------------- + include/asm-powerpc/ps3.h | 15 +- + 4 files changed, 259 insertions(+), 105 deletions(-) + +--- a/drivers/ps3/Makefile ++++ b/drivers/ps3/Makefile +@@ -1,3 +1,4 @@ + obj-$(CONFIG_PS3_VUART) += vuart.o + obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o ++obj-$(CONFIG_PPC_PS3) += sys-manager-core.o + obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o +--- /dev/null ++++ b/drivers/ps3/sys-manager-core.c +@@ -0,0 +1,68 @@ ++/* ++ * PS3 System Manager core. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++ ++/** ++ * Staticly linked routines that allow late binding of a loaded sys-manager ++ * module. ++ */ ++ ++static struct ps3_sys_manager_ops ps3_sys_manager_ops; ++ ++/** ++ * ps3_register_sys_manager_ops - Bind ps3_sys_manager_ops to a module. ++ * @ops: struct ps3_sys_manager_ops. ++ * ++ * To be called from ps3_sys_manager_probe() and ps3_sys_manager_remove() to ++ * register call back ops for power control. Copies data to the static ++ * variable ps3_sys_manager_ops. ++ */ ++ ++void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops) ++{ ++ BUG_ON(!ops); ++ BUG_ON(!ops->dev); ++ ps3_sys_manager_ops = ops ? *ops : ps3_sys_manager_ops; ++} ++EXPORT_SYMBOL_GPL(ps3_sys_manager_register_ops); ++ ++void ps3_sys_manager_power_off(void) ++{ ++ if (ps3_sys_manager_ops.power_off) ++ ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev); ++ ++ printk(KERN_EMERG "System Halted, OK to turn off power\n"); ++ local_irq_disable(); ++ while(1) ++ (void)0; ++} ++ ++void ps3_sys_manager_restart(void) ++{ ++ if (ps3_sys_manager_ops.restart) ++ ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev); ++ ++ printk(KERN_EMERG "System Halted, OK to turn off power\n"); ++ local_irq_disable(); ++ while(1) ++ (void)0; ++} +--- a/drivers/ps3/sys-manager.c ++++ b/drivers/ps3/sys-manager.c +@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("PS3 System Manager") + /** + * ps3_sys_manager - PS3 system manager driver. + * +- * The system manager provides an asyncronous system event notification ++ * The system manager provides an asynchronous system event notification + * mechanism for reporting events like thermal alert and button presses to + * guests. It also provides support to control system shutdown and startup. + * +@@ -52,6 +52,7 @@ MODULE_DESCRIPTION("PS3 System Manager") + * @size: Header size in bytes, curently 16. + * @payload_size: Message payload size in bytes. + * @service_id: Message type, one of enum ps3_sys_manager_service_id. ++ * @request_tag: Unique number to identify reply. + */ + + struct ps3_sys_manager_header { +@@ -61,29 +62,49 @@ struct ps3_sys_manager_header { + u16 reserved_1; + u32 payload_size; + u16 service_id; +- u16 reserved_2[3]; ++ u16 reserved_2; ++ u32 request_tag; + }; + ++#define dump_sm_header(_h) _dump_sm_header(_h, __func__, __LINE__) ++static void __maybe_unused _dump_sm_header( ++ const struct ps3_sys_manager_header* h, const char *func, int line) ++{ ++ pr_debug("%s:%d: version: %xh\n", func, line, h->version); ++ pr_debug("%s:%d: size: %xh\n", func, line, h->size); ++ pr_debug("%s:%d: payload_size: %xh\n", func, line, h->payload_size); ++ pr_debug("%s:%d: service_id: %xh\n", func, line, h->service_id); ++ pr_debug("%s:%d: request_tag: %xh\n", func, line, h->request_tag); ++} ++ + /** +- * @PS3_SM_RX_MSG_LEN - System manager received message length. ++ * @PS3_SM_RX_MSG_LEN_MIN - Shortest received message length. ++ * @PS3_SM_RX_MSG_LEN_MAX - Longest received message length. + * +- * Currently all messages received from the system manager are the same length +- * (16 bytes header + 16 bytes payload = 32 bytes). This knowlege is used to +- * simplify the logic. ++ * Currently all messages received from the system manager are either ++ * (16 bytes header + 8 bytes payload = 24 bytes) or (16 bytes header ++ * + 16 bytes payload = 32 bytes). This knowlege is used to simplify ++ * the logic. + */ + + enum { +- PS3_SM_RX_MSG_LEN = 32, ++ PS3_SM_RX_MSG_LEN_MIN = 24, ++ PS3_SM_RX_MSG_LEN_MAX = 32, + }; + + /** + * enum ps3_sys_manager_service_id - Message header service_id. +- * @PS3_SM_SERVICE_ID_REQUEST: guest --> sys_manager. +- * @PS3_SM_SERVICE_ID_COMMAND: guest <-- sys_manager. +- * @PS3_SM_SERVICE_ID_RESPONSE: guest --> sys_manager. +- * @PS3_SM_SERVICE_ID_SET_ATTR: guest --> sys_manager. +- * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager. +- * @PS3_SM_SERVICE_ID_SET_NEXT_OP: guest --> sys_manager. ++ * @PS3_SM_SERVICE_ID_REQUEST: guest --> sys_manager. ++ * @PS3_SM_SERVICE_ID_REQUEST_ERROR: guest <-- sys_manager. ++ * @PS3_SM_SERVICE_ID_COMMAND: guest <-- sys_manager. ++ * @PS3_SM_SERVICE_ID_RESPONSE: guest --> sys_manager. ++ * @PS3_SM_SERVICE_ID_SET_ATTR: guest --> sys_manager. ++ * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager. ++ * @PS3_SM_SERVICE_ID_SET_NEXT_OP: guest --> sys_manager. ++ * ++ * PS3_SM_SERVICE_ID_REQUEST_ERROR is returned for invalid data values in a ++ * a PS3_SM_SERVICE_ID_REQUEST message. It also seems to be returned when ++ * a REQUEST message is sent at the wrong time. + */ + + enum ps3_sys_manager_service_id { +@@ -93,6 +114,7 @@ enum ps3_sys_manager_service_id { + PS3_SM_SERVICE_ID_COMMAND = 3, + PS3_SM_SERVICE_ID_EXTERN_EVENT = 4, + PS3_SM_SERVICE_ID_SET_NEXT_OP = 5, ++ PS3_SM_SERVICE_ID_REQUEST_ERROR = 6, + PS3_SM_SERVICE_ID_SET_ATTR = 8, + }; + +@@ -185,11 +207,21 @@ enum ps3_sys_manager_cmd { + }; + + /** ++ * ps3_sm_force_power_off - Poweroff helper. ++ * ++ * A global variable used to force a poweroff when the power button has ++ * been pressed irrespective of how init handles the ctrl_alt_del signal. ++ * ++ */ ++ ++static unsigned int ps3_sm_force_power_off; ++ ++/** + * ps3_sys_manager_write - Helper to write a two part message to the vuart. + * + */ + +-static int ps3_sys_manager_write(struct ps3_vuart_port_device *dev, ++static int ps3_sys_manager_write(struct ps3_system_bus_device *dev, + const struct ps3_sys_manager_header *header, const void *payload) + { + int result; +@@ -213,15 +245,10 @@ static int ps3_sys_manager_write(struct + * + */ + +-static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev, ++static int ps3_sys_manager_send_attr(struct ps3_system_bus_device *dev, + enum ps3_sys_manager_attr attr) + { +- static const struct ps3_sys_manager_header header = { +- .version = 1, +- .size = 16, +- .payload_size = 16, +- .service_id = PS3_SM_SERVICE_ID_SET_ATTR, +- }; ++ struct ps3_sys_manager_header header; + struct { + u8 version; + u8 reserved_1[3]; +@@ -232,6 +259,12 @@ static int ps3_sys_manager_send_attr(str + + dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, attr); + ++ memset(&header, 0, sizeof(header)); ++ header.version = 1; ++ header.size = 16; ++ header.payload_size = 16; ++ header.service_id = PS3_SM_SERVICE_ID_SET_ATTR; ++ + memset(&payload, 0, sizeof(payload)); + payload.version = 1; + payload.attribute = attr; +@@ -245,16 +278,11 @@ static int ps3_sys_manager_send_attr(str + * Tell the system manager what to do after this lpar is destroyed. + */ + +-static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev, ++static int ps3_sys_manager_send_next_op(struct ps3_system_bus_device *dev, + enum ps3_sys_manager_next_op op, + enum ps3_sys_manager_wake_source wake_source) + { +- static const struct ps3_sys_manager_header header = { +- .version = 1, +- .size = 16, +- .payload_size = 16, +- .service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP, +- }; ++ struct ps3_sys_manager_header header; + struct { + u8 version; + u8 type; +@@ -268,6 +296,12 @@ static int ps3_sys_manager_send_next_op( + + dev_dbg(&dev->core, "%s:%d: (%xh)\n", __func__, __LINE__, op); + ++ memset(&header, 0, sizeof(header)); ++ header.version = 1; ++ header.size = 16; ++ header.payload_size = 16; ++ header.service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP; ++ + memset(&payload, 0, sizeof(payload)); + payload.version = 3; + payload.type = op; +@@ -286,32 +320,35 @@ static int ps3_sys_manager_send_next_op( + * the command is then communicated back to the system manager with a response + * message. + * +- * Currently, the only supported request it the 'shutdown self' request. ++ * Currently, the only supported request is the 'shutdown self' request. + */ + +-static int ps3_sys_manager_send_request_shutdown(struct ps3_vuart_port_device *dev) ++static int ps3_sys_manager_send_request_shutdown( ++ struct ps3_system_bus_device *dev) + { +- static const struct ps3_sys_manager_header header = { +- .version = 1, +- .size = 16, +- .payload_size = 16, +- .service_id = PS3_SM_SERVICE_ID_REQUEST, +- }; ++ struct ps3_sys_manager_header header; + struct { + u8 version; + u8 type; + u8 gos_id; + u8 reserved_1[13]; +- } static const payload = { +- .version = 1, +- .type = 1, /* shutdown */ +- .gos_id = 0, /* self */ +- }; ++ } payload; + + BUILD_BUG_ON(sizeof(payload) != 16); + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + ++ memset(&header, 0, sizeof(header)); ++ header.version = 1; ++ header.size = 16; ++ header.payload_size = 16; ++ header.service_id = PS3_SM_SERVICE_ID_REQUEST; ++ ++ memset(&payload, 0, sizeof(payload)); ++ payload.version = 1; ++ payload.type = 1; /* shutdown */ ++ payload.gos_id = 0; /* self */ ++ + return ps3_sys_manager_write(dev, &header, &payload); + } + +@@ -323,15 +360,10 @@ static int ps3_sys_manager_send_request_ + * failure of a command sent by the system manager. + */ + +-static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev, ++static int ps3_sys_manager_send_response(struct ps3_system_bus_device *dev, + u64 status) + { +- static const struct ps3_sys_manager_header header = { +- .version = 1, +- .size = 16, +- .payload_size = 16, +- .service_id = PS3_SM_SERVICE_ID_RESPONSE, +- }; ++ struct ps3_sys_manager_header header; + struct { + u8 version; + u8 reserved_1[3]; +@@ -344,6 +376,12 @@ static int ps3_sys_manager_send_response + dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__, + (status ? "nak" : "ack")); + ++ memset(&header, 0, sizeof(header)); ++ header.version = 1; ++ header.size = 16; ++ header.payload_size = 16; ++ header.service_id = PS3_SM_SERVICE_ID_RESPONSE; ++ + memset(&payload, 0, sizeof(payload)); + payload.version = 1; + payload.status = status; +@@ -356,7 +394,7 @@ static int ps3_sys_manager_send_response + * + */ + +-static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev) ++static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev) + { + int result; + struct { +@@ -370,7 +408,7 @@ static int ps3_sys_manager_handle_event( + BUILD_BUG_ON(sizeof(event) != 16); + + result = ps3_vuart_read(dev, &event, sizeof(event)); +- BUG_ON(result); ++ BUG_ON(result && "need to retry here"); + + if (event.version != 1) { + dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n", +@@ -382,11 +420,24 @@ static int ps3_sys_manager_handle_event( + case PS3_SM_EVENT_POWER_PRESSED: + dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n", + __func__, __LINE__); ++ ps3_sm_force_power_off = 1; ++ wmb(); ++ kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */ + break; + case PS3_SM_EVENT_POWER_RELEASED: + dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n", + __func__, __LINE__, event.value); +- kill_cad_pid(SIGINT, 1); ++ break; ++ case PS3_SM_EVENT_RESET_PRESSED: ++ dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n", ++ __func__, __LINE__); ++ ps3_sm_force_power_off = 0; ++ wmb(); ++ kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */ ++ break; ++ case PS3_SM_EVENT_RESET_RELEASED: ++ dev_dbg(&dev->core, "%s:%d: RESET_RELEASED (%u ms)\n", ++ __func__, __LINE__, event.value); + break; + case PS3_SM_EVENT_THERMAL_ALERT: + dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", +@@ -411,7 +462,7 @@ static int ps3_sys_manager_handle_event( + * The system manager sends this in reply to a 'request' message from the guest. + */ + +-static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev) ++static int ps3_sys_manager_handle_cmd(struct ps3_system_bus_device *dev) + { + int result; + struct { +@@ -425,6 +476,7 @@ static int ps3_sys_manager_handle_cmd(st + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + + result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); ++ BUG_ON(result && "need to retry here"); + + if(result) + return result; +@@ -448,9 +500,10 @@ static int ps3_sys_manager_handle_cmd(st + /** + * ps3_sys_manager_handle_msg - First stage msg handler. + * ++ * Can be called directly to manually poll vuart and pump message handler. + */ + +-static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev) ++static int ps3_sys_manager_handle_msg(struct ps3_system_bus_device *dev) + { + int result; + struct ps3_sys_manager_header header; +@@ -464,12 +517,17 @@ static int ps3_sys_manager_handle_msg(st + if (header.version != 1) { + dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n", + __func__, __LINE__, header.version); ++ dump_sm_header(&header); + goto fail_header; + } + + BUILD_BUG_ON(sizeof(header) != 16); +- BUG_ON(header.size != 16); +- BUG_ON(header.payload_size != 16); ++ ++ if(header.size != 16 || (header.payload_size != 8 ++ && header.payload_size != 16)) { ++ dump_sm_header(&header); ++ BUG(); ++ } + + switch (header.service_id) { + case PS3_SM_SERVICE_ID_EXTERN_EVENT: +@@ -478,6 +536,11 @@ static int ps3_sys_manager_handle_msg(st + case PS3_SM_SERVICE_ID_COMMAND: + dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__); + return ps3_sys_manager_handle_cmd(dev); ++ case PS3_SM_SERVICE_ID_REQUEST_ERROR: ++ dev_dbg(&dev->core, "%s:%d: REQUEST_ERROR\n", __func__, ++ __LINE__); ++ dump_sm_header(&header); ++ break; + default: + dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n", + __func__, __LINE__, header.service_id); +@@ -494,45 +557,25 @@ fail_id: + } + + /** +- * ps3_sys_manager_work - Asyncronous read handler. ++ * ps3_sys_manager_final_power_off - The final platform machine_power_off routine. + * +- * Signaled when a complete message arrives at the vuart port. +- */ +- +-static void ps3_sys_manager_work(struct work_struct *work) +-{ +- struct ps3_vuart_port_device *dev = ps3_vuart_work_to_port_device(work); +- +- ps3_sys_manager_handle_msg(dev); +- ps3_vuart_read_async(dev, ps3_sys_manager_work, PS3_SM_RX_MSG_LEN); +-} +- +-struct { +- struct ps3_vuart_port_device *dev; +-} static drv_priv; +- +-/** +- * ps3_sys_manager_restart - The final platform machine_restart routine. +- * +- * This routine never returns. The routine disables asyncronous vuart reads ++ * This routine never returns. The routine disables asynchronous vuart reads + * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge + * the shutdown command sent from the system manager. Soon after the + * acknowledgement is sent the lpar is destroyed by the HV. This routine +- * should only be called from ps3_restart(). ++ * should only be called from ps3_power_off() through ++ * ps3_sys_manager_ops.power_off. + */ + +-void ps3_sys_manager_restart(void) ++static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev) + { +- struct ps3_vuart_port_device *dev = drv_priv.dev; +- +- BUG_ON(!drv_priv.dev); ++ BUG_ON(!dev); + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + + ps3_vuart_cancel_async(dev); + +- ps3_sys_manager_send_attr(dev, 0); +- ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT, ++ ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, + PS3_SM_WAKE_DEFAULT); + ps3_sys_manager_send_request_shutdown(dev); + +@@ -543,26 +586,33 @@ void ps3_sys_manager_restart(void) + } + + /** +- * ps3_sys_manager_power_off - The final platform machine_power_off routine. ++ * ps3_sys_manager_final_restart - The final platform machine_restart routine. + * +- * This routine never returns. The routine disables asyncronous vuart reads ++ * This routine never returns. The routine disables asynchronous vuart reads + * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge + * the shutdown command sent from the system manager. Soon after the + * acknowledgement is sent the lpar is destroyed by the HV. This routine +- * should only be called from ps3_power_off(). ++ * should only be called from ps3_restart() through ps3_sys_manager_ops.restart. + */ + +-void ps3_sys_manager_power_off(void) ++static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev) + { +- struct ps3_vuart_port_device *dev = drv_priv.dev; +- +- BUG_ON(!drv_priv.dev); ++ BUG_ON(!dev); + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + ++ /* Check if we got here via a power button event. */ ++ ++ if(ps3_sm_force_power_off) { ++ dev_dbg(&dev->core, "%s:%d: forcing poweroff\n", ++ __func__, __LINE__); ++ ps3_sys_manager_final_power_off(dev); ++ } ++ + ps3_vuart_cancel_async(dev); + +- ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN, ++ ps3_sys_manager_send_attr(dev, 0); ++ ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT, + PS3_SM_WAKE_DEFAULT); + ps3_sys_manager_send_request_shutdown(dev); + +@@ -572,31 +622,60 @@ void ps3_sys_manager_power_off(void) + ps3_sys_manager_handle_msg(dev); + } + +-static int ps3_sys_manager_probe(struct ps3_vuart_port_device *dev) ++/** ++ * ps3_sys_manager_work - Asynchronous read handler. ++ * ++ * Signaled when PS3_SM_RX_MSG_LEN_MIN bytes arrive at the vuart port. ++ */ ++ ++static void ps3_sys_manager_work(struct ps3_system_bus_device *dev) ++{ ++ ps3_sys_manager_handle_msg(dev); ++ ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); ++} ++ ++static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev) + { + int result; ++ struct ps3_sys_manager_ops ops; + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + +- BUG_ON(drv_priv.dev); +- drv_priv.dev = dev; ++ ops.power_off = ps3_sys_manager_final_power_off; ++ ops.restart = ps3_sys_manager_final_restart; ++ ops.dev = dev; ++ ++ /* ps3_sys_manager_register_ops copies ops. */ ++ ++ ps3_sys_manager_register_ops(&ops); + + result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL); + BUG_ON(result); + +- result = ps3_vuart_read_async(dev, ps3_sys_manager_work, +- PS3_SM_RX_MSG_LEN); ++ result = ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); + BUG_ON(result); + + return result; + } + ++static int ps3_sys_manager_remove(struct ps3_system_bus_device *dev) ++{ ++ dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); ++ return 0; ++} ++ ++static void ps3_sys_manager_shutdown(struct ps3_system_bus_device *dev) ++{ ++ dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); ++} ++ + static struct ps3_vuart_port_driver ps3_sys_manager = { +- .match_id = PS3_MATCH_ID_SYSTEM_MANAGER, +- .core = { +- .name = "ps3_sys_manager", +- }, ++ .core.match_id = PS3_MATCH_ID_SYSTEM_MANAGER, ++ .core.core.name = "ps3_sys_manager", + .probe = ps3_sys_manager_probe, ++ .remove = ps3_sys_manager_remove, ++ .shutdown = ps3_sys_manager_shutdown, ++ .work = ps3_sys_manager_work, + }; + + static int __init ps3_sys_manager_init(void) +@@ -608,3 +687,6 @@ static int __init ps3_sys_manager_init(v + } + + module_init(ps3_sys_manager_init); ++/* Module remove not supported. */ ++ ++MODULE_ALIAS(PS3_MODULE_ALIAS_SYSTEM_MANAGER); +--- a/include/asm-powerpc/ps3.h ++++ b/include/asm-powerpc/ps3.h +@@ -410,13 +410,15 @@ extern struct bus_type ps3_system_bus_ty + + /* system manager */ + +-#ifdef CONFIG_PS3_SYS_MANAGER +-void ps3_sys_manager_restart(void); ++struct ps3_sys_manager_ops { ++ struct ps3_system_bus_device *dev; ++ void (*power_off)(struct ps3_system_bus_device *dev); ++ void (*restart)(struct ps3_system_bus_device *dev); ++}; ++ ++void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops); + void ps3_sys_manager_power_off(void); +-#else +-static inline void ps3_sys_manager_restart(void) {} +-static inline void ps3_sys_manager_power_off(void) {} +-#endif ++void ps3_sys_manager_restart(void); + + struct ps3_prealloc { + const char *name; +@@ -427,4 +429,5 @@ struct ps3_prealloc { + + extern struct ps3_prealloc ps3fb_videomemory; + ++ + #endif --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/07-ps3av-include.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/07-ps3av-include.patch @@ -0,0 +1,40 @@ +Subject: PS3: Make ps3av.h usable from user space +From: Masashi Kimoto + +The user applications to manage the PS3 AV modes can use values +defined in this header. + +CC: Masashi Kimoto +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + include/asm-powerpc/Kbuild | 1 + + include/asm-powerpc/ps3av.h | 2 ++ + 2 files changed, 3 insertions(+) + +--- a/include/asm-powerpc/Kbuild ++++ b/include/asm-powerpc/Kbuild +@@ -34,6 +34,7 @@ unifdef-y += elf.h + unifdef-y += nvram.h + unifdef-y += param.h + unifdef-y += posix_types.h ++unifdef-y += ps3av.h + unifdef-y += ptrace.h + unifdef-y += seccomp.h + unifdef-y += signal.h +--- a/include/asm-powerpc/ps3av.h ++++ b/include/asm-powerpc/ps3av.h +@@ -321,6 +321,7 @@ + #define PS3AV_MODE_RGB 0x0020 + + ++#ifdef __KERNEL__ + /** command packet structure **/ + struct ps3av_send_hdr { + u16 version; +@@ -723,4 +724,5 @@ extern int ps3av_audio_mute(int); + extern int ps3av_dev_open(void); + extern int ps3av_dev_close(void); + ++#endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_PS3AV_H_ */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/31-powerpc-zimage-asm-preprocess.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/31-powerpc-zimage-asm-preprocess.patch @@ -0,0 +1,31 @@ +Subject: powerpc: Bootwrapper asm preprocessing + +Make some changes to improve the preprocessing of bootwrapper +assmbly files. + - Remove the -traditional flag from BOOTAFLAGS, which does not + allow preprocessor string concatenations. + - Add source include paths to BOOTAFLAGS. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/Makefile | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/boot/Makefile ++++ b/arch/powerpc/boot/Makefile +@@ -23,13 +23,14 @@ BOOTCFLAGS := -Wall -Wundef -Wstrict- + -fno-strict-aliasing -Os -msoft-float -pipe \ + -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ + -isystem $(shell $(CROSS32CC) -print-file-name=include) +-BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc ++BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc + + ifeq ($(call cc-option-yn, -fstack-protector),y) + BOOTCFLAGS += -fno-stack-protector + endif + + BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) ++BOOTAFLAGS += -I$(obj) -I$(srctree)/$(obj) + + $(obj)/44x.o: BOOTCFLAGS += -mcpu=440 + $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/36-ps3-gelic-wireless.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/36-ps3-gelic-wireless.patch @@ -0,0 +1,2503 @@ +Subject: ps3: wireless LAN driver + +Add support of the internal wireless LAN of PS3. + +Signed-off-by: Masakazu Mokuno +--- + drivers/net/Kconfig | 7 + drivers/net/Makefile | 4 + drivers/net/gelic_net.c | 30 + drivers/net/gelic_net.h | 227 ++++ + drivers/net/gelic_wireless.c | 2125 +++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 2389 insertions(+), 4 deletions(-) + +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -2274,6 +2274,13 @@ config GELIC_NET + To compile this driver as a module, choose M here: the + module will be called gelic_net. + ++config GELIC_WIRELESS ++ bool "Gelic net Wireless Extension" ++ depends on GELIC_NET ++ select WIRELESS_EXT ++ help ++ Wireless Extension support for Gelic Gigabit Ethernet driver ++ + config GIANFAR + tristate "Gianfar Ethernet" + depends on 85xx || 83xx || PPC_86xx +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -60,7 +60,9 @@ obj-$(CONFIG_TIGON3) += tg3.o + obj-$(CONFIG_BNX2) += bnx2.o + spidernet-y += spider_net.o spider_net_ethtool.o + obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o +-obj-$(CONFIG_GELIC_NET) += gelic_net.o ++obj-$(CONFIG_GELIC_NET) += ps3_gelic.o ++gelic-$(CONFIG_GELIC_WIRELESS) += gelic_wireless.o ++ps3_gelic-objs += gelic_net.o $(gelic-y) + obj-$(CONFIG_TC35815) += tc35815.o + obj-$(CONFIG_SKGE) += skge.o + obj-$(CONFIG_SKY2) += sky2.o +--- a/drivers/net/gelic_net.c ++++ b/drivers/net/gelic_net.c +@@ -550,6 +550,9 @@ static int gelic_net_stop(struct net_dev + { + struct gelic_net_card *card = netdev_priv(netdev); + ++#ifdef CONFIG_GELIC_WIRELESS ++ gelicw_down(netdev); ++#endif + netif_poll_disable(netdev); + netif_stop_queue(netdev); + +@@ -1023,6 +1026,9 @@ static irqreturn_t gelic_net_interrupt(i + /* start pending DMA */ + gelic_net_xmit(NULL, netdev); + } ++#ifdef CONFIG_GELIC_WIRELESS ++ gelicw_interrupt(netdev, status); ++#endif + return IRQ_HANDLED; + } + +@@ -1118,13 +1124,18 @@ static int gelic_net_open(struct net_dev + + card->tx_dma_progress = 0; + card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT; +- ++#ifdef CONFIG_GELIC_WIRELESS ++ card->ghiintmask |= GELICW_DEVICE_CMD_COMP | GELICW_DEVICE_EVENT_RECV; ++#endif + gelic_net_set_irq_mask(card, card->ghiintmask); + gelic_net_enable_rxdmac(card); + + netif_start_queue(netdev); + netif_carrier_on(netdev); + netif_poll_enable(netdev); ++#ifdef CONFIG_GELIC_WIRELESS ++ gelicw_up(netdev); ++#endif + + return 0; + +@@ -1203,7 +1214,12 @@ static u32 gelic_net_get_link(struct net + link = 1; + else + link = 0; +- ++#ifdef CONFIG_GELIC_WIRELESS ++ /* (v1 & GELIC_NET_LINK_UP) is always 0 in wireless mode */ ++ if (gelicw_is_associated(netdev)) { ++ link = 1; ++ } ++#endif + return link; + } + +@@ -1394,7 +1410,12 @@ static int gelic_net_setup_netdev(struct + } + if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) + card->vlan_index = GELIC_NET_VLAN_WIRED - 1; +- ++#ifdef CONFIG_GELIC_WIRELESS ++ card->w.card = card; ++ /* init wireless extension */ ++ /* No wireless vlan_index:-1 */ ++ gelicw_setup_netdev(netdev, card->vlan_index); ++#endif + status = register_netdev(netdev); + if (status) { + dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n", +@@ -1528,6 +1549,9 @@ static int ps3_gelic_driver_remove (stru + + card = ps3_system_bus_get_driver_data(dev); + ++#ifdef CONFIG_GELIC_WIRELESS ++ gelicw_remove(card->netdev); ++#endif + wait_event(card->waitq, + atomic_read(&card->tx_timeout_task_counter) == 0); + +--- a/drivers/net/gelic_net.h ++++ b/drivers/net/gelic_net.h +@@ -30,6 +30,9 @@ + #ifndef _GELIC_NET_H + #define _GELIC_NET_H + ++#include ++#include ++ + #define GELIC_NET_DRV_NAME "Gelic Network Driver" + #define GELIC_NET_DRV_VERSION "1.0" + +@@ -170,6 +173,220 @@ enum gelic_net_descr_status { + + #define GELIC_NET_PORT 2 /* for port status */ + ++/* wireless */ ++#define GELICW_WIRELESS_NOT_EXIST 0 ++#define GELICW_WIRELESS_SUPPORTED 1 ++#define GELICW_WIRELESS_ON 2 ++#define GELICW_WIRELESS_SHUTDOWN 3 ++/* state */ ++#define GELICW_STATE_DOWN 0 ++#define GELICW_STATE_UP 1 ++#define GELICW_STATE_SCANNING 2 ++#define GELICW_STATE_SCAN_DONE 3 ++#define GELICW_STATE_ASSOCIATED 4 ++ ++/* cmd_send_flg */ ++#define GELICW_CMD_SEND_NONE 0x00 ++#define GELICW_CMD_SEND_COMMON 0x01 ++#define GELICW_CMD_SEND_ENCODE 0x02 ++#define GELICW_CMD_SEND_SCAN 0x04 ++#define GELICW_CMD_SEND_ALL (GELICW_CMD_SEND_COMMON \ ++ | GELICW_CMD_SEND_ENCODE \ ++ | GELICW_CMD_SEND_SCAN) ++ ++#define GELICW_SCAN_INTERVAL (HZ) ++ ++#ifdef DEBUG ++#define CH_INFO_FAIL 0x0600 /* debug */ ++#else ++#define CH_INFO_FAIL 0 ++#endif ++ ++ ++/* net_control command */ ++#define GELICW_SET_PORT 3 /* control Ether port */ ++#define GELICW_GET_INFO 6 /* get supported channels */ ++#define GELICW_SET_CMD 9 /* set configuration */ ++#define GELICW_GET_RES 10 /* get command response */ ++#define GELICW_GET_EVENT 11 /* get event from device */ ++/* net_control command data buffer */ ++#define GELICW_DATA_BUF_SIZE 0x1000 ++ ++/* GELICW_SET_CMD params */ ++#define GELICW_CMD_START 1 ++#define GELICW_CMD_STOP 2 ++#define GELICW_CMD_SCAN 3 ++#define GELICW_CMD_GET_SCAN 4 ++#define GELICW_CMD_SET_CONFIG 5 ++#define GELICW_CMD_GET_CONFIG 6 ++#define GELICW_CMD_SET_WEP 7 ++#define GELICW_CMD_GET_WEP 8 ++#define GELICW_CMD_SET_WPA 9 ++#define GELICW_CMD_GET_WPA 10 ++#define GELICW_CMD_GET_RSSI 11 ++ ++/* GELICW_SET_PORT params */ ++#define GELICW_ETHER_PORT 2 ++#define GELICW_PORT_DOWN 0 /* Ether port off */ ++#define GELICW_PORT_UP 4 /* Ether port on (auto neg) */ ++ ++/* interrupt status bit */ ++#define GELICW_DEVICE_CMD_COMP (1UL << 31) ++#define GELICW_DEVICE_EVENT_RECV (1UL << 30) ++ ++/* GELICW_GET_EVENT ID */ ++#define GELICW_EVENT_UNKNOWN 0x00 ++#define GELICW_EVENT_DEVICE_READY 0x01 ++#define GELICW_EVENT_SCAN_COMPLETED 0x02 ++#define GELICW_EVENT_DEAUTH 0x04 ++#define GELICW_EVENT_BEACON_LOST 0x08 ++#define GELICW_EVENT_CONNECTED 0x10 ++#define GELICW_EVENT_WPA_CONNECTED 0x20 ++#define GELICW_EVENT_WPA_ERROR 0x40 ++#define GELICW_EVENT_NO_ENTRY (-6) ++ ++#define MAX_IW_PRIV_SIZE 32 ++ ++/* structure of data buffer for lv1_net_contol */ ++/* wep_config: sec */ ++#define GELICW_WEP_SEC_NONE 0 ++#define GELICW_WEP_SEC_40BIT 1 ++#define GELICW_WEP_SEC_104BIT 2 ++struct wep_config { ++ u16 sec; ++ u8 key[4][16]; ++} __attribute__ ((packed)); ++ ++/* wpa_config: sec */ ++#define GELICW_WPA_SEC_NONE 0 ++#define GELICW_WPA_SEC_TKIP 1 ++#define GELICW_WPA_SEC_AES 2 ++/* wpa_config: psk_type */ ++#define GELICW_PSK_PASSPHRASE 0 ++#define GELICW_PSK_64HEX 1 ++struct wpa_config { ++ u16 sec; ++ u16 psk_type; ++ u8 psk_material[64]; /* key */ ++} __attribute__ ((packed)); ++ ++/* common_config: bss_type */ ++#define GELICW_BSS_INFRA 0 ++#define GELICW_BSS_ADHOC 1 ++/* common_config: auth_method */ ++#define GELICW_AUTH_OPEN 0 ++#define GELICW_AUTH_SHARED 1 ++/* common_config: op_mode */ ++#define GELICW_OP_MODE_11BG 0 ++#define GELICW_OP_MODE_11B 1 ++#define GELICW_OP_MODE_11G 2 ++struct common_config { ++ u16 scan_index; /* index of scan_desc list */ ++ u16 bss_type; ++ u16 auth_method; ++ u16 op_mode; ++} __attribute__ ((packed)); ++ ++/* scan_descriptor: security */ ++#define GELICW_SEC_TYPE_NONE 0x0000 ++#define GELICW_SEC_TYPE_WEP 0x0100 ++#define GELICW_SEC_TYPE_WEP40 0x0101 ++#define GELICW_SEC_TYPE_WEP104 0x0102 ++#define GELICW_SEC_TYPE_TKIP 0x0201 ++#define GELICW_SEC_TYPE_AES 0x0202 ++#define GELICW_SEC_TYPE_WEP_MASK 0xFF00 ++struct scan_desc { ++ u16 size; ++ u16 rssi; ++ u16 channel; ++ u16 beacon_period; ++ u16 capability; ++ u16 security; ++ u64 bssid; ++ u8 essid[32]; ++ u8 rate[16]; ++ u8 ext_rate[16]; ++ u32 reserved1; ++ u32 reserved2; ++ u32 reserved3; ++ u32 reserved4; ++} __attribute__ ((packed)); ++ ++/* rssi_descriptor */ ++struct rssi_desc { ++ u16 rssi; /* max rssi = 100 */ ++} __attribute__ ((packed)); ++ ++ ++struct gelicw_bss { ++ u8 bssid[ETH_ALEN]; ++ u8 channel; ++ u8 mode; ++ u8 essid_len; ++ u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */ ++ ++ u16 capability; ++ u16 beacon_interval; ++ ++ u8 rates_len; ++ u8 rates[MAX_RATES_LENGTH]; ++ u8 rates_ex_len; ++ u8 rates_ex[MAX_RATES_EX_LENGTH]; ++ u8 rssi; ++ ++ /* scan results have sec_info instead of rsn_ie or wpa_ie */ ++ u16 sec_info; ++}; ++ ++/* max station count of station list which hvc returns */ ++#define MAX_SCAN_BSS (16) ++ ++struct gelic_wireless { ++ struct gelic_net_card *card; ++ struct completion cmd_done, rssi_done; ++ struct work_struct work_event, work_start_done; ++ struct delayed_work work_rssi, work_scan_all, work_scan_essid; ++ struct delayed_work work_common, work_encode; ++ struct delayed_work work_start, work_stop, work_roam; ++ wait_queue_head_t waitq_cmd, waitq_scan; ++ ++ u64 cmd_tag, cmd_id; ++ u8 cmd_send_flg; ++ ++ struct iw_public_data wireless_data; ++ u8 *data_buf; /* data buffer for lv1_net_control */ ++ ++ u8 wireless; /* wireless support */ ++ u8 state; ++ u8 scan_all; /* essid scan or all scan */ ++ u8 essid_search; /* essid background scan */ ++ u8 is_assoc; ++ ++ u16 ch_info; /* supoprted channels */ ++ u8 wireless_mode; /* 11b/g */ ++ u8 channel; /* current ch */ ++ u8 iw_mode; /* INFRA or Ad-hoc */ ++ u8 rssi; ++ u8 essid_len; ++ u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */ ++ u8 nick[IW_ESSID_MAX_SIZE + 1]; ++ u8 bssid[ETH_ALEN]; ++ ++ u8 key_index; ++ u8 key[WEP_KEYS][IW_ENCODING_TOKEN_MAX]; /* 4 * 64byte */ ++ u8 key_len[WEP_KEYS]; ++ u8 key_alg; /* key algorithm */ ++ u8 auth_mode; /* authenticaton mode */ ++ ++ u8 bss_index; /* current bss in bss_list */ ++ u8 num_bss_list; ++ u8 bss_key_alg; /* key alg of bss */ ++ u8 wap_bssid[ETH_ALEN]; ++ unsigned long last_scan; /* last scan time */ ++ struct gelicw_bss current_bss; ++ struct gelicw_bss bss_list[MAX_SCAN_BSS]; ++}; ++ + /* size of hardware part of gelic descriptor */ + #define GELIC_NET_DESCR_SIZE (32) + struct gelic_net_descr { +@@ -225,9 +442,19 @@ struct gelic_net_card { + wait_queue_head_t waitq; + + struct gelic_net_descr *tx_top, *rx_top; ++#ifdef CONFIG_GELIC_WIRELESS ++ struct gelic_wireless w; ++#endif + struct gelic_net_descr descr[0]; + }; + + + extern unsigned long p_to_lp(long pa); ++extern int gelicw_setup_netdev(struct net_device *netdev, int wi); ++extern void gelicw_up(struct net_device *netdev); ++extern int gelicw_down(struct net_device *netdev); ++extern void gelicw_remove(struct net_device *netdev); ++extern void gelicw_interrupt(struct net_device *netdev, u64 status); ++extern int gelicw_is_associated(struct net_device *netdev); ++ + #endif //_GELIC_NET_H +--- /dev/null ++++ b/drivers/net/gelic_wireless.c +@@ -0,0 +1,2125 @@ ++/* ++ * gelic_wireless.c: wireless extension for gelic_net ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#undef DEBUG ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "gelic_net.h" ++ ++static struct iw_handler_def gelicw_handler_def; ++ ++/* ++ * Data tables ++ */ ++static const u32 freq_list[] = { ++ 2412, 2417, 2422, 2427, 2432, ++ 2437, 2442, 2447, 2452, 2457, ++ 2462, 2467, 2472, 2484 }; ++ ++static const u32 bitrate_list[] = { ++ 1000000, 2000000, 5500000, 11000000, /* 11b */ ++ 6000000, 9000000, 12000000, 18000000, ++ 24000000, 36000000, 48000000, 54000000 ++}; ++#define GELICW_NUM_11B_BITRATES 4 /* 802.11b: 1 ~ 11 Mb/s */ ++ ++static inline struct device * ntodev(struct net_device *netdev) ++{ ++ return &((struct gelic_net_card *)netdev_priv(netdev))->dev->core; ++} ++ ++static inline struct device * wtodev(struct gelic_wireless *w) ++{ ++ return &w->card->dev->core; ++} ++static inline struct gelic_wireless *gelicw_priv(struct net_device *netdev) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ return &card->w; ++} ++static inline unsigned int bus_id(struct gelic_wireless *w) ++{ ++ return w->card->dev->bus_id; ++} ++static inline unsigned int dev_id(struct gelic_wireless *w) ++{ ++ return w->card->dev->dev_id; ++} ++ ++/* control wired or wireless */ ++static void gelicw_vlan_mode(struct net_device *netdev, int mode) ++{ ++ struct gelic_net_card *card = netdev_priv(netdev); ++ ++ if ((mode < GELIC_NET_VLAN_WIRED) || ++ (mode > GELIC_NET_VLAN_WIRELESS)) ++ return; ++ ++ card->vlan_index = mode - 1; ++} ++ ++/* wireless_send_event */ ++static void notify_assoc_event(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ union iwreq_data wrqu; ++ ++ cancel_delayed_work(&w->work_scan_all); ++ cancel_delayed_work(&w->work_scan_essid); ++ ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ if (w->state < GELICW_STATE_ASSOCIATED) { ++ dev_dbg(ntodev(netdev), "notify disassociated\n"); ++ w->is_assoc = 0; ++ memset(w->bssid, 0, ETH_ALEN); ++ } else { ++ dev_dbg(ntodev(netdev), "notify associated\n"); ++ w->channel = w->current_bss.channel; ++ w->is_assoc = 1; ++ memcpy(w->bssid, w->current_bss.bssid, ETH_ALEN); ++ } ++ memcpy(wrqu.ap_addr.sa_data, w->bssid, ETH_ALEN); ++ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); ++} ++ ++/* association/disassociation */ ++static void gelicw_assoc(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (w->state == GELICW_STATE_ASSOCIATED) ++ return; ++ schedule_delayed_work(&w->work_start, 0); ++} ++ ++static int gelicw_disassoc(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ memset(w->bssid, 0, ETH_ALEN); /* clear current bssid */ ++ if (w->state < GELICW_STATE_ASSOCIATED) ++ return 0; ++ ++ schedule_delayed_work(&w->work_stop, 0); ++ w->state = GELICW_STATE_SCAN_DONE; ++ /* notify disassociation */ ++ notify_assoc_event(netdev); ++ ++ return 0; ++} ++ ++static void gelicw_reassoc(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (w->cmd_send_flg != GELICW_CMD_SEND_ALL) ++ return; ++ ++ if (!gelicw_disassoc(netdev)) ++ gelicw_assoc(netdev); ++} ++ ++ ++/* ++ * lv1_net_control command ++ */ ++/* control Ether port */ ++static int gelicw_cmd_set_port(struct net_device *netdev, int mode) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 tag, val; ++ int status; ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_PORT, GELICW_ETHER_PORT, mode, 0, ++ &tag, &val); ++ if (status) ++ dev_dbg(ntodev(netdev), "GELICW_SET_PORT failed:%d\n", status); ++ return status; ++} ++ ++/* check support channels */ ++static int gelicw_cmd_get_ch_info(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 ch_info, val; ++ int status; ++ ++ if (w->state < GELICW_STATE_UP) ++ return -EIO; ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_INFO, 0, 0 , 0, ++ &ch_info, &val); ++ if (status) { ++ dev_dbg(ntodev(netdev), "GELICW_GET_INFO failed:%d\n", status); ++ w->ch_info = CH_INFO_FAIL; ++ } else { ++ dev_dbg(ntodev(netdev), "ch_info:%lx val:%lx\n", ch_info, val); ++ w->ch_info = ch_info >> 48; /* MSB 16bit shows supported channnels */ ++ } ++ return status; ++} ++ ++ ++/* ++ * lv1_net_control GELICW_SET_CMD command ++ * queued using schedule_work() ++ */ ++/* association */ ++static void gelicw_cmd_start(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 val; ++ int status; ++ ++ if (w->state < GELICW_STATE_SCAN_DONE) ++ return; ++ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_START\n"); ++ w->cmd_id = GELICW_CMD_START; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, 0, 0, ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_START failed:%d\n", status); ++ } ++} ++ ++/* association done */ ++static void gelicw_cmd_start_done(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 res, val; ++ int status; ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, ++ &res, &val); ++ w->cmd_tag = 0; ++ wake_up_interruptible(&w->waitq_cmd); ++ ++ if (status || res) ++ dev_dbg(ntodev(netdev), "GELICW_CMD_START res:%d,%ld\n", status, res); ++} ++ ++/* disassociation */ ++static void gelicw_cmd_stop(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 res, val; ++ int status; ++ ++ if (w->state < GELICW_STATE_SCAN_DONE) ++ return; ++ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_STOP\n"); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_STOP; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, 0, 0, ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_STOP failed:%d\n", status); ++ return; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(ntodev(netdev), "GELICW_CMD_STOP res:%d,%ld\n", status, res); ++ return; ++ } ++} ++ ++/* get rssi */ ++static void gelicw_cmd_rssi(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 lpar, res, val; ++ int status; ++ struct rssi_desc *rssi; ++ ++ if (w->state < GELICW_STATE_ASSOCIATED) { ++ w->rssi = 0; ++ complete(&w->rssi_done); ++ return; ++ } ++ ++ lpar = ps3_mm_phys_to_lpar(__pa(w->data_buf)); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_GET_RSSI; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, 0, 0, ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ w->rssi = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_GET_RSSI failed:%d\n", status); ++ } else { ++ wait_for_completion_interruptible(&w->cmd_done); ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, lpar, sizeof(*rssi), ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ w->rssi = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_GET_RSSI res:%d,%ld\n", status, res); ++ } ++ rssi = (struct rssi_desc *)w->data_buf; ++ w->rssi = rssi->rssi; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_GET_RSSI:%d\n", rssi->rssi); ++ } ++ ++ complete(&w->rssi_done); ++} ++ ++/* set common configuration */ ++static int gelicw_cmd_common(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 lpar, res, val; ++ int status; ++ struct common_config *config; ++ ++ if (w->state < GELICW_STATE_SCAN_DONE) ++ return -EIO; ++ ++ lpar = ps3_mm_phys_to_lpar(__pa(w->data_buf)); ++ config = (struct common_config *)w->data_buf; ++ config->scan_index = w->bss_index; ++ config->bss_type = (w->iw_mode == IW_MODE_ADHOC) ? ++ GELICW_BSS_ADHOC : GELICW_BSS_INFRA; ++ config->auth_method = (w->auth_mode == IW_AUTH_ALG_SHARED_KEY) ? ++ GELICW_AUTH_SHARED : GELICW_AUTH_OPEN; ++ switch (w->wireless_mode) { ++ case IEEE_B: ++ config->op_mode = GELICW_OP_MODE_11B; ++ break; ++ case IEEE_G: ++ config->op_mode = GELICW_OP_MODE_11G; ++ break; ++ case IEEE_B | IEEE_G: ++ default: ++ /* default 11bg mode */ ++ config->op_mode = GELICW_OP_MODE_11BG; ++ break; ++ } ++ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_CONFIG: index:%d type:%d auth:%d mode:%d\n",\ ++ config->scan_index, config->bss_type,\ ++ config->auth_method,config->op_mode); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_SET_CONFIG; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, ++ lpar, sizeof(struct common_config), ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_CONFIG failed:%d\n", status); ++ return status; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_CONFIG res:%d,%ld\n", status, res); ++ return -EFAULT; ++ } ++ ++ w->cmd_send_flg |= GELICW_CMD_SEND_COMMON; ++ ++ return 0; ++} ++ ++#define h2i(c) (isdigit(c) ? c - '0' : toupper(c) - 'A' + 10) ++/* send WEP/WPA configuration */ ++static int gelicw_cmd_encode(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 res, val, lpar; ++ int status; ++ struct wep_config *config; ++ struct wpa_config *wpa_config; ++ ++ u8 *key, key_len; ++ ++ if (w->state < GELICW_STATE_SCAN_DONE) ++ return -EIO; ++ ++ lpar = ps3_mm_phys_to_lpar(__pa(w->data_buf)); ++ ++ if (w->key_alg == IW_ENCODE_ALG_WEP || ++ w->key_alg == IW_ENCODE_ALG_NONE) { ++ /* WEP */ ++ config = (struct wep_config *)w->data_buf; ++ memset(config, 0, sizeof(struct wep_config)); ++ ++ /* check key len */ ++ key_len = w->key_len[w->key_index]; ++ key = w->key[w->key_index]; ++ if (w->key_alg == IW_ENCODE_ALG_NONE) ++ config->sec = GELICW_WEP_SEC_NONE; ++ else ++ config->sec = (key_len == 5) ? GELICW_WEP_SEC_40BIT : ++ GELICW_WEP_SEC_104BIT; ++ /* copy key */ ++ memcpy(config->key[w->key_index], key, key_len); ++ ++ /* send wep config */ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WEP\n"); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_SET_WEP; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, ++ lpar, sizeof(struct wep_config), ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WEP failed:%d\n", status); ++ goto err; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WEP res:%d,%ld\n", status, res); ++ status = -EFAULT; ++ goto err; ++ } ++ } else { ++ /* WPA */ ++ wpa_config = (struct wpa_config *)w->data_buf; ++ memset(wpa_config, 0, sizeof(struct wpa_config)); ++ ++ switch (w->key_alg) { ++ case IW_ENCODE_ALG_TKIP: ++ wpa_config->sec = GELICW_WPA_SEC_TKIP; ++ break; ++ default: ++ case IW_ENCODE_ALG_CCMP: ++ wpa_config->sec = GELICW_WPA_SEC_AES; ++ break; ++ } ++ /* check key len */ ++ key = w->key[w->key_index]; ++ key_len = w->key_len[w->key_index]; ++ ++ if (key_len > 64) key_len = 64; ++ if (key_len != 64) { ++ /* if key_len isn't 64byte ,it should be passphrase */ ++ /* pass phrase */ ++ memcpy(wpa_config->psk_material, key, key_len); ++ wpa_config->psk_type = GELICW_PSK_PASSPHRASE; ++ } else { ++ int i; ++ /* 64 hex */ ++ for (i = 0; i < 32; i++) ++ wpa_config->psk_material[i] = ++ h2i(key[2 * i]) * 16 ++ + h2i(key[2 * i + 1]); ++ wpa_config->psk_type = GELICW_PSK_64HEX; ++ } ++ ++ /* send wpa config */ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WPA:type:%d\n", wpa_config->psk_type); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_SET_WPA; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, ++ lpar, sizeof(struct wpa_config), ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WPA failed:%d\n", status); ++ goto err; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SET_WPA res:%d,%ld\n", status, res); ++ status = -EFAULT; ++ goto err; ++ } ++ } ++ ++ w->cmd_send_flg |= GELICW_CMD_SEND_ENCODE; ++ /* (re)associate */ ++ gelicw_reassoc(netdev); ++ ++ return 0; ++err: ++ gelicw_disassoc(netdev); ++ return status; ++} ++ ++static int gelicw_is_ap_11b(struct gelicw_bss *list) ++{ ++ if (list->rates_len + list->rates_ex_len == GELICW_NUM_11B_BITRATES) ++ return 1; ++ else ++ return 0; ++} ++ ++/* get scan results */ ++static int gelicw_cmd_get_scan(struct gelic_wireless *w) ++{ ++ u64 lpar, res, val; ++ int status; ++ struct scan_desc *desc; ++ int i, j; ++ u8 *p; ++ ++ ++ /* get scan */ ++ dev_dbg(wtodev(w), "GELICW_CMD_GET_SCAN\n"); ++ init_completion(&w->cmd_done); ++ w->cmd_id = GELICW_CMD_GET_SCAN; ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, 0, 0, ++ &w->cmd_tag, &val); ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(wtodev(w), "GELICW_CMD_GET_SCAN failed:%d\n", status); ++ return status; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ lpar = ps3_mm_phys_to_lpar(__pa(w->data_buf)); ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, lpar, PAGE_SIZE, ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(wtodev(w), "GELICW_CMD_GET_SCAN res:%d,%ld\n", ++ status, res); ++ return -EFAULT; ++ } ++ ++ desc = (struct scan_desc *)w->data_buf; ++ for (i = 0; ++ i < val / sizeof(struct scan_desc) && i < MAX_SCAN_BSS; ++ i++) { ++ struct gelicw_bss *bss = &w->bss_list[i]; ++ ++ bss->rates_len = 0; ++ for (j = 0; j < MAX_RATES_LENGTH; j++) ++ if (desc[i].rate[j]) ++ bss->rates[bss->rates_len++] = desc[i].rate[j]; ++ bss->rates_ex_len = 0; ++ for (j = 0; j < MAX_RATES_EX_LENGTH; j++) ++ if (desc[i].ext_rate[j]) ++ bss->rates_ex[bss->rates_ex_len++] ++ = desc[i].ext_rate[j]; ++ ++ if (desc[i].capability & 0x3) { ++ if (desc[i].capability & 0x1) ++ bss->mode = IW_MODE_INFRA; ++ else ++ bss->mode = IW_MODE_ADHOC; ++ } ++ bss->channel = desc[i].channel; ++ bss->essid_len = strnlen(desc[i].essid, IW_ESSID_MAX_SIZE); ++ bss->rssi = (u8)desc[i].rssi; ++ bss->capability = desc[i].capability; ++ bss->beacon_interval = desc[i].beacon_period; ++ memset(bss->essid, 0, sizeof(bss->essid)); ++ memcpy(bss->essid, desc[i].essid, bss->essid_len); ++ p = (u8 *)&desc[i].bssid; ++ memcpy(bss->bssid, &p[2], ETH_ALEN);/* bssid:64bit in desc */ ++ bss->sec_info = desc[i].security; ++ } ++ w->num_bss_list = i; ++ ++ if (w->num_bss_list) ++ return 0; /* ap found */ ++ else ++ return -1; /* no ap found */ ++} ++ ++/* search bssid in bss list */ ++static int gelicw_search_bss_list(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ int i; ++ int check_bss = 0, check_11g = 0, found_bss, found_11g; ++ ++ if (!w->num_bss_list) ++ return -1; /* no bss list */ ++ ++ if (memcmp(off, w->wap_bssid, ETH_ALEN)) ++ check_bss = 1; ++ ++ /* wireless op_mode seems not working with CMD_SET_CONFIG */ ++ if (w->wireless_mode == IEEE_G) ++ check_11g = 1; ++ ++ if (!check_bss && !check_11g) ++ return 0; /* no check bssid, wmode */ ++ ++ for (i = 0; i < w->num_bss_list; i++) { ++ found_bss = found_11g = 1; ++ if (check_bss && ++ memcmp(w->bss_list[i].bssid, w->wap_bssid, ETH_ALEN)) ++ found_bss = 0; /* not found */ ++ ++ if (check_11g && ++ gelicw_is_ap_11b(&w->bss_list[i])) ++ found_11g = 0; /* not found */ ++ ++ if (found_bss && found_11g) ++ break; ++ } ++ ++ if (i == w->num_bss_list) ++ return -1; /* not found */ ++ else ++ return i; ++} ++ ++/* scan done */ ++static void gelicw_scan_complete(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ int res; ++ int bss_index; ++ ++ /* get scan results */ ++ res = gelicw_cmd_get_scan(w); ++ if (w->is_assoc) ++ w->state = GELICW_STATE_ASSOCIATED; ++ else ++ w->state = GELICW_STATE_SCAN_DONE; ++ ++ if (res) { ++ /* No AP found */ ++ if (!w->scan_all) { ++ /* no specified AP */ ++ gelicw_disassoc(netdev); ++ /* rescan */ ++ if (w->essid_search && w->essid_len) ++ schedule_delayed_work(&w->work_scan_essid, ++ GELICW_SCAN_INTERVAL); ++ return; ++ } ++ } ++ ++ if (w->scan_all) { ++ /* all params should be set again after scan */ ++ w->cmd_send_flg = 0; ++ return; ++ } ++ ++ bss_index = gelicw_search_bss_list(netdev); ++ if (bss_index < 0) { ++ /* no wap_bssid in bss_list */ ++ if (w->essid_search && w->essid_len) ++ schedule_delayed_work(&w->work_scan_essid, ++ GELICW_SCAN_INTERVAL); ++ return; ++ } ++ w->bss_index = (u8)bss_index; ++ w->current_bss = w->bss_list[w->bss_index]; ++ ++ /* essid search complete */ ++ w->essid_search = 0; ++ w->cmd_send_flg |= GELICW_CMD_SEND_SCAN; ++ ++ /* (re)connect to AP */ ++ if (w->is_assoc) { ++ /* notify disassociation */ ++ w->state = GELICW_STATE_SCAN_DONE; ++ notify_assoc_event(netdev); ++ } ++ schedule_delayed_work(&w->work_common, 0); ++ schedule_delayed_work(&w->work_encode, 0); ++} ++ ++/* start scan */ ++static int gelicw_cmd_set_scan(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 res, val, lpar; ++ int status; ++ u8 *p; ++ ++ if (w->state < GELICW_STATE_UP) { ++ w->scan_all = 0; ++ return -EIO; ++ } ++ if (!w->scan_all && !w->essid_len) ++ return -EINVAL; /* unsupported essid ANY */ ++ ++ /* set device wired to wireless when essid is set */ ++ if (!w->scan_all && w->wireless < GELICW_WIRELESS_ON) { ++ gelicw_vlan_mode(netdev, GELIC_NET_VLAN_WIRELESS); ++ gelicw_cmd_set_port(netdev, GELICW_PORT_DOWN); ++ w->wireless = GELICW_WIRELESS_ON; ++ } ++ ++ p = (u8 *)w->data_buf; ++ lpar = ps3_mm_phys_to_lpar(__pa(w->data_buf)); ++ ++ /* avoid frequent scanning */ ++ if (!w->essid_search && /* background scan off */ ++ w->scan_all && ++ (time_before64(get_jiffies_64(), w->last_scan + 5 * HZ))) ++ return 0; ++ ++ w->bss_key_alg = IW_ENCODE_ALG_NONE; ++ ++ init_completion(&w->cmd_done); ++ w->state = GELICW_STATE_SCANNING; ++ w->cmd_id = GELICW_CMD_SCAN; ++ ++ if (w->scan_all) { ++ /* scan all ch */ ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SCAN all\n"); ++ w->last_scan = get_jiffies_64(); /* last scan time */ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, 0, 0, ++ &w->cmd_tag, &val); ++ } else { ++ /* scan essid */ ++ memset(p, 0, 32); ++ memcpy(p, w->essid, w->essid_len); ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SCAN essid\n"); ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_SET_CMD, w->cmd_id, lpar, 32, ++ &w->cmd_tag, &val); ++ } ++ ++ if (status) { ++ w->cmd_tag = 0; ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SCAN failed:%d\n", status); ++ return status; ++ } ++ wait_for_completion_interruptible(&w->cmd_done); ++ ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_RES, w->cmd_tag, 0, 0, ++ &res, &val); ++ w->cmd_tag = 0; ++ if (status || res) { ++ dev_dbg(ntodev(netdev), "GELICW_CMD_SCAN res:%d,%ld\n", status, res); ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static void gelicw_send_common_config(struct net_device *netdev, ++ u8 *cur, u8 mode) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (*cur != mode) { ++ *cur = mode; ++ if (w->state < GELICW_STATE_SCAN_DONE) ++ return; ++ ++ if (!(w->cmd_send_flg & GELICW_CMD_SEND_SCAN) && ++ w->essid_len) ++ /* scan essid and set other params */ ++ schedule_delayed_work(&w->work_scan_essid, 0); ++ else { ++ schedule_delayed_work(&w->work_common, 0); ++ if (w->cmd_send_flg ++ & GELICW_CMD_SEND_ENCODE) ++ /* (re)send encode key */ ++ schedule_delayed_work(&w->work_encode, 0); ++ } ++ } ++} ++ ++ ++/* ++ * work queue ++ */ ++static void gelicw_work_rssi(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_rssi.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag) { ++ schedule_delayed_work(&w->work_rssi, HZ / 5); ++ return; ++ } ++ ++ gelicw_cmd_rssi(netdev); ++} ++ ++static void gelicw_work_scan_all(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_scan_all.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag || w->state == GELICW_STATE_SCANNING) { ++ schedule_delayed_work(&w->work_scan_all, HZ / 5); ++ return; ++ } ++ ++ w->scan_all = 1; ++ gelicw_cmd_set_scan(netdev); ++} ++ ++static void gelicw_work_scan_essid(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_scan_essid.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag || w->scan_all || w->state == GELICW_STATE_SCANNING) { ++ schedule_delayed_work(&w->work_scan_essid, HZ / 5); ++ return; ++ } ++ w->bss_index = 0; ++ w->scan_all = 0; ++ gelicw_cmd_set_scan(netdev); ++} ++ ++static void gelicw_work_common(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_common.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag) { ++ schedule_delayed_work(&w->work_common, HZ / 5); ++ return; ++ } ++ gelicw_cmd_common(netdev); ++} ++ ++static void gelicw_work_encode(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_encode.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag) { ++ schedule_delayed_work(&w->work_encode, HZ / 5); ++ return; ++ } ++ gelicw_cmd_encode(netdev); ++} ++ ++static void gelicw_work_start(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_start.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag) { ++ schedule_delayed_work(&w->work_start, HZ / 5); ++ return; ++ } ++ gelicw_cmd_start(netdev); ++} ++ ++static void gelicw_work_start_done(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_start_done); ++ struct net_device *netdev = w->card->netdev; ++ ++ gelicw_cmd_start_done(netdev); ++} ++ ++static void gelicw_work_stop(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_stop.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag) { ++ schedule_delayed_work(&w->work_stop, HZ / 5); ++ return; ++ } ++ gelicw_cmd_stop(netdev); ++} ++ ++static void gelicw_work_roam(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_roam.work); ++ struct net_device *netdev = w->card->netdev; ++ ++ if (w->cmd_tag || w->scan_all || w->state == GELICW_STATE_SCANNING) { ++ schedule_delayed_work(&w->work_roam, HZ / 5); ++ return; ++ } ++ gelicw_cmd_stop(netdev); ++ w->bss_index = 0; ++ w->scan_all = 0; ++ gelicw_cmd_set_scan(netdev); ++} ++ ++/* ++ * Event handler ++ */ ++#define GELICW_EVENT_LOOP_MAX 16 ++static void gelicw_event(struct work_struct *work) ++{ ++ struct gelic_wireless *w = ++ container_of(work, struct gelic_wireless, work_event); ++ struct net_device *netdev = w->card->netdev; ++ u64 event_type, val; ++ int i, status; ++ ++ for (i = 0; i < GELICW_EVENT_LOOP_MAX; i++) { ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_EVENT, 0, 0 , 0, ++ &event_type, &val); ++ if (status == GELICW_EVENT_NO_ENTRY) ++ /* got all events */ ++ break; ++ else if (status){ ++ dev_dbg(ntodev(netdev), "GELICW_GET_EVENT failed:%d\n", status); ++ return; ++ } ++ switch(event_type) { ++ case GELICW_EVENT_DEVICE_READY: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_DEVICE_READY\n"); ++ break; ++ case GELICW_EVENT_SCAN_COMPLETED: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_SCAN_COMPLETED\n"); ++ gelicw_scan_complete(netdev); ++ break; ++ case GELICW_EVENT_BEACON_LOST: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_BEACON_LOST\n"); ++ w->state = GELICW_STATE_SCAN_DONE; ++ notify_assoc_event(netdev); ++ /* roaming */ ++ w->essid_search = 1; ++ schedule_delayed_work(&w->work_roam, 0); ++ break; ++ case GELICW_EVENT_CONNECTED: ++ { ++ u16 ap_sec; ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_CONNECTED\n"); ++ /* this event ocuured with any key_alg */ ++ ap_sec = w->current_bss.sec_info; ++ if (w->key_alg == IW_ENCODE_ALG_NONE) { ++ /* no encryption */ ++ if (ap_sec == 0) { ++ w->state = GELICW_STATE_ASSOCIATED; ++ notify_assoc_event(netdev); ++ } ++ } else if (w->key_alg == IW_ENCODE_ALG_WEP){ ++ if ((ap_sec & GELICW_SEC_TYPE_WEP_MASK) ++ == GELICW_SEC_TYPE_WEP) { ++ /* wep */ ++ w->state = GELICW_STATE_ASSOCIATED; ++ notify_assoc_event(netdev); ++ } ++ } ++ break; ++ } ++ case GELICW_EVENT_WPA_CONNECTED: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_WPA_CONNECTED\n"); ++ w->state = GELICW_STATE_ASSOCIATED; ++ notify_assoc_event(netdev); ++ break; ++ case GELICW_EVENT_WPA_ERROR: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_WPA_ERROR\n"); ++ break; ++ default: ++ dev_dbg(ntodev(netdev), " GELICW_EVENT_UNKNOWN\n"); ++ break; ++ } ++ } ++} ++ ++static void gelicw_clear_event(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u64 event_type, val; ++ int i, status; ++ ++ for (i = 0; i < GELICW_EVENT_LOOP_MAX; i++) { ++ status = lv1_net_control(bus_id(w), dev_id(w), ++ GELICW_GET_EVENT, 0, 0 , 0, ++ &event_type, &val); ++ if (status) ++ return;/* got all events */ ++ ++ switch(event_type) { ++ case GELICW_EVENT_SCAN_COMPLETED: ++ w->state = GELICW_STATE_SCAN_DONE; ++ wake_up_interruptible(&w->waitq_scan); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++/* ++ * gelic_net support function ++ */ ++static void gelicw_clear_params(struct gelic_wireless *w) ++{ ++ int i; ++ ++ /* clear status */ ++ w->state = GELICW_STATE_DOWN; ++ w->cmd_send_flg = 0; ++ w->scan_all = 0; ++ w->is_assoc = 0; ++ w->essid_search = 0; ++ w->cmd_tag = 0; ++ w->cmd_id = 0; ++ w->last_scan = 0; ++ ++ /* default mode and settings */ ++ w->essid_len = 0; ++ w->essid[0] = '\0'; ++ w->nick[0] = '\0'; ++ w->iw_mode = IW_MODE_INFRA; ++ w->auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; ++ w->wireless_mode = IEEE_B | IEEE_G; ++ w->bss_index = 0; ++ memset(w->bssid, 0, ETH_ALEN); ++ memset(w->wap_bssid, 0, ETH_ALEN); ++ ++ /* init key */ ++ w->key_index = 0; ++ for (i = 0; i < WEP_KEYS; i++) { ++ w->key[i][0] = '\0'; ++ w->key_len[i] = 0; ++ } ++ w->key_alg = IW_ENCODE_ALG_NONE; ++ w->bss_key_alg = IW_ENCODE_ALG_NONE; ++} ++ ++int gelicw_setup_netdev(struct net_device *netdev, int wi) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (wi < 0) { ++ /* PS3 low model has no wireless */ ++ dev_info(ntodev(netdev), "No wireless dvice in this system\n"); ++ w->wireless = 0; ++ return 0; ++ } ++ /* version check */ ++ if (ps3_compare_firmware_version(1, 6, 0) < 0) { ++ dev_info(ntodev(netdev), ++ "firmware is too old for wireless.\n"); ++ w->wireless = 0; ++ return 0; ++ } ++ /* we need 4K aligned, 16 units of scan_desc sized */ ++ BUILD_BUG_ON(PAGE_SIZE < sizeof(struct scan_desc) * MAX_SCAN_BSS); ++ w->data_buf = (u8*)get_zeroed_page(GFP_KERNEL); ++ if (!w->data_buf) { ++ w->wireless = 0; ++ dev_info(ntodev(netdev), "%s:get_page failed\n", __func__); ++ return -ENOMEM; ++ } ++ ++ w->wireless = GELICW_WIRELESS_SUPPORTED; ++ ++ w->ch_info = 0; ++ w->channel = 0; ++ netdev->wireless_data = &w->wireless_data; ++ netdev->wireless_handlers = &gelicw_handler_def; ++ INIT_WORK(&w->work_event, gelicw_event); ++ INIT_WORK(&w->work_start_done, gelicw_work_start_done); ++ INIT_DELAYED_WORK(&w->work_rssi, gelicw_work_rssi); ++ INIT_DELAYED_WORK(&w->work_scan_all, gelicw_work_scan_all); ++ INIT_DELAYED_WORK(&w->work_scan_essid, gelicw_work_scan_essid); ++ INIT_DELAYED_WORK(&w->work_common, gelicw_work_common); ++ INIT_DELAYED_WORK(&w->work_encode, gelicw_work_encode); ++ INIT_DELAYED_WORK(&w->work_start, gelicw_work_start); ++ INIT_DELAYED_WORK(&w->work_stop, gelicw_work_stop); ++ INIT_DELAYED_WORK(&w->work_roam, gelicw_work_roam); ++ init_waitqueue_head(&w->waitq_cmd); ++ init_waitqueue_head(&w->waitq_scan); ++ ++ gelicw_clear_params(w); ++ ++ return 0; ++} ++ ++void gelicw_up(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (!w->wireless) ++ return; ++ ++ dev_dbg(ntodev(netdev), "gelicw_up\n"); ++ if (w->state < GELICW_STATE_UP) ++ w->state = GELICW_STATE_UP; ++ ++ /* start essid scanning */ ++ if (w->essid_len) ++ schedule_delayed_work(&w->work_scan_essid, 0); ++} ++ ++int gelicw_down(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (!w->wireless || w->state == GELICW_STATE_DOWN) ++ return 0; ++ ++ dev_dbg(ntodev(netdev), "gelicw_down\n"); ++ w->wireless = GELICW_WIRELESS_SHUTDOWN; ++ flush_scheduled_work(); ++ ++ /* check cmd_tag of CMD_START */ ++ if (w->cmd_id == GELICW_CMD_START) ++ wait_event_interruptible(w->waitq_cmd, !w->cmd_tag); ++ /* wait scan done */ ++ if (w->state == GELICW_STATE_SCANNING) { ++ wait_event_interruptible(w->waitq_scan, ++ w->state != GELICW_STATE_SCANNING); ++ gelicw_cmd_get_scan(w); ++ } ++ ++ gelicw_cmd_stop(netdev); ++ if (w->is_assoc) { ++ w->state = GELICW_STATE_DOWN; ++ notify_assoc_event(netdev); ++ } ++ gelicw_clear_params(w); ++ ++ /* set device wireless to wired */ ++ gelicw_vlan_mode(netdev, GELIC_NET_VLAN_WIRED); ++ gelicw_cmd_set_port(netdev, GELICW_PORT_UP); ++ w->wireless = GELICW_WIRELESS_SUPPORTED; ++ ++ return 0; ++} ++ ++void gelicw_remove(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (!w->wireless) ++ return; ++ ++ dev_dbg(ntodev(netdev), "gelicw_remove\n"); ++ gelicw_down(netdev); ++ w->wireless = 0; ++ netdev->wireless_handlers = NULL; ++ free_page((unsigned long)w->data_buf); ++} ++ ++void gelicw_interrupt(struct net_device *netdev, u64 status) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (!w->wireless) ++ return; ++ ++ if (status & GELICW_DEVICE_CMD_COMP) { ++ dev_dbg(ntodev(netdev), "GELICW_DEVICE_CMD_COMP\n"); ++ if (w->cmd_id == GELICW_CMD_START) ++ schedule_work(&w->work_start_done); ++ else ++ complete(&w->cmd_done); ++ } ++ if (status & GELICW_DEVICE_EVENT_RECV) { ++ dev_dbg(ntodev(netdev), "GELICW_DEVICE_EVENT_RECV\n"); ++ if (w->wireless == GELICW_WIRELESS_SHUTDOWN) ++ gelicw_clear_event(netdev); ++ else ++ schedule_work(&w->work_event); ++ } ++} ++ ++int gelicw_is_associated(struct net_device *netdev) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ if (!w->wireless) ++ return 0; ++ ++ return w->is_assoc; ++} ++ ++ ++/* ++ * Wireless externsions ++ */ ++static int gelicw_get_name(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx: get_name\n"); ++ if (w->state < GELICW_STATE_UP) { ++ strcpy(wrqu->name, "radio off"); ++ return 0; ++ } ++ ++ if (w->wireless_mode == IEEE_B || ++ (w->is_assoc && gelicw_is_ap_11b(&w->current_bss))) ++ strcpy(wrqu->name, "IEEE 802.11b"); ++ else { ++ switch (w->wireless_mode) { ++ case IEEE_G: ++ strcpy(wrqu->name, "IEEE 802.11g"); ++ break; ++ case IEEE_B | IEEE_G: ++ default: ++ strcpy(wrqu->name, "IEEE 802.11bg"); ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++static int gelicw_set_freq(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_freq *fwrq = &wrqu->freq; ++ int ch; ++ ++ dev_dbg(ntodev(netdev), "wx: set_freq e:%d m:%d\n", fwrq->e, fwrq->m); ++ if (w->is_assoc || w->state < GELICW_STATE_UP) ++ return 0; ++ ++ /* this setting has no effect for INFRA mode */ ++ if (fwrq->e == 1) { ++ u32 f = fwrq->m / 100000; ++ int i; ++ for (i = 0; i < ARRAY_SIZE(freq_list); i++) ++ if (freq_list[i] == f) ++ break; ++ if (i == ARRAY_SIZE(freq_list)) ++ return -EINVAL; ++ fwrq->m = i + 1; /* ch number */ ++ fwrq->e = 0; ++ } ++ if (fwrq->e > 0) ++ return -EINVAL; ++ ++ ch = fwrq->m; ++ if (ch < 1) ++ w->channel = 0; /* auto */ ++ else if (ch > ARRAY_SIZE(freq_list)) ++ return -EINVAL; ++ else { ++ /* check supported channnel */ ++ if (!w->ch_info) ++ gelicw_cmd_get_ch_info(netdev); ++ if (w->ch_info & (1 << (ch - 1))) ++ w->channel = ch; ++ else ++ return -EINVAL; ++ } ++ dev_dbg(ntodev(netdev), " set cnannel: %d\n", w->channel); ++ ++ return 0; ++} ++ ++static int gelicw_get_freq(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx: get_freq:%d\n", w->channel); ++ if (w->channel == 0) ++ wrqu->freq.m = 0; ++ else ++ wrqu->freq.m = freq_list[w->channel - 1] * 100000; ++ wrqu->freq.e = 1; ++ ++ return 0; ++} ++ ++static int gelicw_set_mode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ int mode = wrqu->mode; ++ u8 iw_mode = IW_MODE_INFRA; ++ ++ dev_dbg(ntodev(netdev), "wx: set_mode:%x\n",mode); ++ switch (mode) { ++ case IW_MODE_ADHOC: ++ dev_dbg(ntodev(netdev), "IW_MODE_ADHOC\n"); ++ iw_mode = mode; ++ return -EOPNOTSUPP; /* adhoc not supported */ ++ case IW_MODE_INFRA: ++ default: ++ dev_dbg(ntodev(netdev), "IW_MODE_INFRA\n"); ++ iw_mode = IW_MODE_INFRA; ++ break; ++ } ++ ++ /* send common config */ ++ gelicw_send_common_config(netdev, &w->iw_mode, iw_mode); ++ ++ return 0; ++} ++ ++static int gelicw_get_mode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx: get_mode\n"); ++ wrqu->mode = w->iw_mode; ++ ++ return 0; ++} ++ ++static inline int gelicw_qual2level(int qual) ++{ ++ return (qual * 4 - 820)/10; /* FIXME: dummy */ ++} ++ ++static int gelicw_get_range(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_range *range = (struct iw_range *)extra; ++ int num_ch, i; ++ ++ dev_dbg(ntodev(netdev), "wx: get_range\n"); ++ wrqu->data.length = sizeof(*range); ++ memset(range, 0, sizeof(*range)); ++ ++ /* wireless extension */ ++ range->we_version_compiled = WIRELESS_EXT; ++ range->we_version_source = 19; ++ ++ /* supported bitrates */ ++ if (w->wireless_mode == IEEE_B) ++ range->num_bitrates = GELICW_NUM_11B_BITRATES; ++ else ++ range->num_bitrates = ARRAY_SIZE(bitrate_list); ++ range->throughput = bitrate_list[range->num_bitrates -1] / 2; /* half */ ++ for (i = 0; i < range->num_bitrates; i++) ++ range->bitrate[i] = bitrate_list[i]; ++ ++ range->max_qual.qual = 100; /* relative value */ ++ range->max_qual.level = 0; ++ range->avg_qual.qual = 50; ++ range->avg_qual.level = 0; ++ range->sensitivity = 0; ++ ++ /* encryption capabilities */ ++ range->encoding_size[0] = 5; /* 40bit WEP */ ++ range->encoding_size[1] = 13; /* 104bit WEP */ ++ range->encoding_size[2] = 64; /* WPA-PSK */ ++ range->num_encoding_sizes = 3; ++ range->max_encoding_tokens = WEP_KEYS; ++ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | ++ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; ++ ++ /* freq */ ++ if (!w->ch_info) ++ gelicw_cmd_get_ch_info(netdev); /* get supported freq */ ++ ++ num_ch = 0; ++ for (i = 0; i < ARRAY_SIZE(freq_list); i++) ++ if (w->ch_info & (1 << i)) { ++ range->freq[num_ch].i = i + 1; ++ range->freq[num_ch].m = freq_list[i] * 100000; ++ range->freq[num_ch].e = 1; ++ if (++num_ch == IW_MAX_FREQUENCIES) ++ break; ++ } ++ ++ range->num_channels = num_ch; ++ range->num_frequency = num_ch; ++ ++ /* event capabilities */ ++ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | ++ IW_EVENT_CAPA_MASK(SIOCGIWAP)); ++ range->event_capa[1] = IW_EVENT_CAPA_K_1; ++ ++ return 0; ++} ++ ++static int gelicw_set_wap(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ static const u8 any[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; ++ static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ ++ dev_dbg(ntodev(netdev), "wx: set_wap\n"); ++ if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) ++ return -EINVAL; ++ ++ if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || ++ !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { ++ if (!memcmp(off, w->wap_bssid, ETH_ALEN)) ++ return 0; /* ap off, no change */ ++ else { ++ memset(w->wap_bssid, 0, ETH_ALEN); ++ /* start scan */ ++ } ++ } else if (!memcmp(w->wap_bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) ++ /* no change */ ++ return 0; ++ else if (!memcmp(w->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { ++ /* current bss */ ++ memcpy(w->wap_bssid, wrqu->ap_addr.sa_data, ETH_ALEN); ++ return 0; ++ } else ++ memcpy(w->wap_bssid, wrqu->ap_addr.sa_data, ETH_ALEN); ++ ++ /* start scan */ ++ if (w->essid_len && w->state >= GELICW_STATE_SCAN_DONE) { ++ gelicw_disassoc(netdev); ++ /* scan essid */ ++ cancel_delayed_work(&w->work_scan_all); ++ cancel_delayed_work(&w->work_scan_essid); ++ w->essid_search = 1; ++ schedule_delayed_work(&w->work_scan_essid, 0); ++ } ++ ++ return 0; ++} ++ ++static int gelicw_get_wap(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx: get_wap\n"); ++ wrqu->ap_addr.sa_family = ARPHRD_ETHER; ++ memcpy(wrqu->ap_addr.sa_data, w->bssid, ETH_ALEN); ++ ++ return 0; ++} ++ ++static int gelicw_set_scan(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx: set_scan\n"); ++ if (w->state < GELICW_STATE_UP) ++ return -EIO; ++ ++ /* cancel scan */ ++ cancel_delayed_work(&w->work_scan_all); ++ cancel_delayed_work(&w->work_scan_essid); ++ ++ schedule_delayed_work(&w->work_scan_all, 0); ++ ++ return 0; ++} ++ ++#define MAX_CUSTOM_LEN 64 ++static char *gelicw_translate_scan(struct net_device *netdev, ++ char *start, char *stop, ++ struct gelicw_bss *list) ++{ ++ char custom[MAX_CUSTOM_LEN]; ++ struct iw_event iwe; ++ int i; ++ char *p, *current_val; ++ ++ /* BSSID */ ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN); ++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); ++ ++ /* ESSID */ ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = list->essid_len; ++ start = iwe_stream_add_point(start, stop, &iwe, list->essid); ++ ++ /* protocol name */ ++ iwe.cmd = SIOCGIWNAME; ++ if (gelicw_is_ap_11b(list)) ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); ++ else ++ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); ++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN); ++ ++ /* MODE */ ++ iwe.cmd = SIOCGIWMODE; ++ iwe.u.mode = list->mode; ++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); ++ ++ /* FREQ */ ++ iwe.cmd = SIOCGIWFREQ; ++ iwe.u.freq.m = list->channel; ++ iwe.u.freq.e = 0; ++ iwe.u.freq.i = 0; ++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); ++ ++ /* ENCODE */ ++ iwe.cmd = SIOCGIWENCODE; ++ if (list->capability & WLAN_CAPABILITY_PRIVACY) ++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ else ++ iwe.u.data.flags = IW_ENCODE_DISABLED; ++ iwe.u.data.length = 0; ++ start = iwe_stream_add_point(start, stop, &iwe, list->essid); ++ ++ /* QUAL */ ++ iwe.cmd = IWEVQUAL; ++ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | ++ IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ iwe.u.qual.qual = list->rssi; ++ iwe.u.qual.level = gelicw_qual2level(list->rssi); ++ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); ++ ++ /* RATE */ ++ current_val = start + IW_EV_LCP_LEN; ++ iwe.cmd = SIOCGIWRATE; ++ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; ++ for (i = 0; i < list->rates_len; i++) { ++ iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000); ++ current_val = iwe_stream_add_value(start, current_val, stop, ++ &iwe, IW_EV_PARAM_LEN); ++ } ++ for (i = 0; i < list->rates_ex_len; i++) { ++ iwe.u.bitrate.value = ((list->rates_ex[i] & 0x7f) * 500000); ++ current_val = iwe_stream_add_value(start, current_val, stop, ++ &iwe, IW_EV_PARAM_LEN); ++ } ++ if ((current_val - start) > IW_EV_LCP_LEN) ++ start = current_val; ++ ++ /* Extra */ ++ /* BEACON */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ p = custom; ++ p += snprintf(p, MAX_CUSTOM_LEN, "bcn_int=%d", list->beacon_interval); ++ iwe.u.data.length = p - custom; ++ start = iwe_stream_add_point(start, stop, &iwe, custom); ++ ++ /* AP security */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ p = custom; ++ p += snprintf(p, MAX_CUSTOM_LEN, "ap_sec=%04X", list->sec_info); ++ iwe.u.data.length = p - custom; ++ start = iwe_stream_add_point(start, stop, &iwe, custom); ++ ++ return start; ++} ++ ++static int gelicw_get_scan(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ int i; ++ char *ev = extra; ++ char *stop = ev + wrqu->data.length; ++ ++ dev_dbg(ntodev(netdev), "wx: get_scan \n"); ++ switch (w->state) { ++ case GELICW_STATE_DOWN: ++ case GELICW_STATE_UP: ++ return 0; /* no scan results */ ++ case GELICW_STATE_SCANNING: ++ return -EAGAIN; /* now scanning */ ++ case GELICW_STATE_SCAN_DONE: ++ if (!w->scan_all) /* essid scan */ ++ return -EAGAIN; ++ break; ++ default: ++ break; ++ } ++ ++ w->scan_all = 0; ++ for (i = 0; i < w->num_bss_list; i++) ++ ev = gelicw_translate_scan(netdev, ev, stop, &w->bss_list[i]); ++ wrqu->data.length = ev - extra; ++ wrqu->data.flags = 0; ++ ++ /* start background scan */ ++ if (w->essid_search) ++ schedule_delayed_work(&w->work_scan_essid, ++ GELICW_SCAN_INTERVAL); ++ ++ return 0; ++} ++ ++static int gelicw_set_essid(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u16 length = 0; ++ ++ dev_dbg(ntodev(netdev), "wx:set_essid\n"); ++ /* cancel scan */ ++ w->essid_search = 0; ++ cancel_delayed_work(&w->work_scan_all); ++ cancel_delayed_work(&w->work_scan_essid); ++ ++ if (wrqu->essid.flags && wrqu->essid.length) ++ length = wrqu->essid.length; ++ ++ if (length == 0) { ++ /* essid ANY scan not supported */ ++ dev_dbg(ntodev(netdev), "ESSID ANY\n"); ++ w->essid_len = 0; /* clear essid */ ++ w->essid[0] = '\0'; ++ return 0; ++ } else { ++ /* check essid */ ++ if (length > IW_ESSID_MAX_SIZE) ++ return -EINVAL; ++ if (w->essid_len == length && ++ !strncmp(w->essid, extra, length)) { ++ /* same essid */ ++ if (w->is_assoc) ++ return 0; ++ } else { ++ /* set new essid */ ++ w->essid_len = length; ++ memcpy(w->essid, extra, length); ++ } ++ } ++ /* start essid scan */ ++ w->essid_search = 1; ++ schedule_delayed_work(&w->work_scan_essid, 0); ++ ++ return 0; ++} ++ ++static int gelicw_get_essid(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx:get_essid\n"); ++ if (w->essid_len) { ++ memcpy(extra, w->essid, w->essid_len); ++ wrqu->essid.length = w->essid_len; ++ wrqu->essid.flags = 1; ++ } else { ++ wrqu->essid.length = 0; ++ wrqu->essid.flags = 0; ++ } ++ ++ return 0; ++} ++ ++static int gelicw_set_nick(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ u32 len = wrqu->data.length; ++ ++ dev_dbg(ntodev(netdev), "wx:set_nick\n"); ++ if (len > IW_ESSID_MAX_SIZE) ++ return -EINVAL; ++ ++ memset(w->nick, 0, sizeof(w->nick)); ++ memcpy(w->nick, extra, len); ++ ++ return 0; ++} ++ ++static int gelicw_get_nick(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx:get_nick\n"); ++ wrqu->data.length = strlen(w->nick); ++ memcpy(extra, w->nick, wrqu->data.length); ++ wrqu->data.flags = 1; ++ ++ return 0; ++} ++ ++static int gelicw_set_rate(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ dev_dbg(ntodev(netdev), "wx:set_rate:%d\n", wrqu->bitrate.value); ++ if (wrqu->bitrate.value == -1) ++ return 0; /* auto rate only */ ++ ++ return -EOPNOTSUPP; ++} ++ ++static int gelicw_get_rate(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx:get_rate\n"); ++ ++ if (w->wireless_mode == IEEE_B || ++ (w->is_assoc && gelicw_is_ap_11b(&w->current_bss))) ++ wrqu->bitrate.value = bitrate_list[GELICW_NUM_11B_BITRATES -1]; ++ else ++ wrqu->bitrate.value = bitrate_list[ARRAY_SIZE(bitrate_list) -1]; ++ ++ wrqu->bitrate.fixed = 0; ++ ++ return 0; ++} ++ ++static int gelicw_set_encode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_point *enc = &wrqu->encoding; ++ int i, index, key_index; ++ ++ dev_dbg(ntodev(netdev), "wx:set_encode: flags:%x\n", enc->flags ); ++ index = enc->flags & IW_ENCODE_INDEX; ++ if (index < 0 || index > WEP_KEYS) ++ return -EINVAL; ++ index--; ++ ++ if (enc->length > IW_ENCODING_TOKEN_MAX) ++ return -EINVAL; ++ ++ if (index != -1) ++ w->key_index = index; ++ key_index = w->key_index; ++ ++ if (enc->flags & IW_ENCODE_DISABLED) { ++ /* disable encryption */ ++ if (index == -1) { ++ /* disable all */ ++ w->key_alg = IW_ENCODE_ALG_NONE; ++ for (i = 0; i < WEP_KEYS; i++) ++ w->key_len[i] = 0; ++ } else ++ w->key_len[key_index] = 0; ++ } else if (enc->flags & IW_ENCODE_NOKEY) { ++ /* key not changed */ ++ if (w->key_alg == IW_ENCODE_ALG_NONE) ++ w->key_alg = IW_ENCODE_ALG_WEP; /* default wep */ ++ } else { ++ /* enable encryption */ ++ w->key_len[key_index] = enc->length; ++ if (w->key_alg == IW_ENCODE_ALG_NONE) ++ w->key_alg = IW_ENCODE_ALG_WEP; /* default wep */ ++ memcpy(w->key[key_index], extra, w->key_len[key_index]); ++ } ++ dev_dbg(ntodev(netdev), "key %d len:%d alg:%x\n",\ ++ key_index, w->key_len[key_index], w->key_alg); ++ ++ if (w->state >= GELICW_STATE_SCAN_DONE && ++ w->cmd_send_flg == 0 && w->essid_len) ++ /* scan essid and set other params */ ++ schedule_delayed_work(&w->work_scan_essid, 0); ++ else ++ schedule_delayed_work(&w->work_encode, 0); ++ ++ return 0; ++} ++ ++static int gelicw_get_encode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_point *enc = &wrqu->encoding; ++ int index, key_index; ++ ++ dev_dbg(ntodev(netdev), "wx:get_encode\n"); ++ index = enc->flags & IW_ENCODE_INDEX; ++ if (index < 0 || index > WEP_KEYS) ++ return -EINVAL; ++ ++ index--; ++ key_index = (index == -1 ? w->key_index : index); ++ enc->flags = key_index + 1; ++ ++ if (w->key_alg == IW_ENCODE_ALG_NONE || !w->key_len[key_index]) { ++ /* no encryption */ ++ enc->flags |= IW_ENCODE_DISABLED; ++ enc->length = 0; ++ } else { ++ enc->flags |= IW_ENCODE_NOKEY; ++ enc->length = w->key_len[key_index]; ++ memset(extra, 0, w->key_len[key_index]); ++ } ++ ++ return 0; ++} ++ ++static int gelicw_set_auth(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_param *param = &wrqu->param; ++ int value = param->value; ++ int ret = 0; ++ ++ dev_dbg(ntodev(netdev), "wx:set_auth:%x\n", param->flags & IW_AUTH_INDEX); ++ switch(param->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ case IW_AUTH_CIPHER_PAIRWISE: ++ case IW_AUTH_CIPHER_GROUP: ++ case IW_AUTH_KEY_MGMT: ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ case IW_AUTH_DROP_UNENCRYPTED: ++ case IW_AUTH_WPA_ENABLED: ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ case IW_AUTH_ROAMING_CONTROL: ++ case IW_AUTH_PRIVACY_INVOKED: ++ /* ignore */ ++ dev_dbg(ntodev(netdev), "IW_AUTH(%x)\n", param->flags & IW_AUTH_INDEX); ++ break; ++ case IW_AUTH_80211_AUTH_ALG: ++ dev_dbg(ntodev(netdev), "IW_AUTH_80211_AUTH_ALG:\n"); ++ if (value & IW_AUTH_ALG_SHARED_KEY) ++ w->auth_mode = IW_AUTH_ALG_SHARED_KEY; ++ else if (value & IW_AUTH_ALG_OPEN_SYSTEM) ++ w->auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; ++ else ++ ret = -EINVAL; ++ break; ++ default: ++ dev_dbg(ntodev(netdev), "IW_AUTH_UNKNOWN flags:%x\n", param->flags); ++ ret = -EOPNOTSUPP; ++ } ++ ++ return ret; ++} ++ ++static int gelicw_get_auth(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_param *param = &wrqu->param; ++ ++ dev_dbg(ntodev(netdev), "wx:get_auth\n"); ++ switch(param->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_80211_AUTH_ALG: ++ param->value = w->auth_mode; ++ break; ++ case IW_AUTH_WPA_ENABLED: ++ if ((w->key_alg & IW_ENCODE_ALG_TKIP) || ++ (w->key_alg & IW_ENCODE_ALG_CCMP)) ++ param->value = 1; ++ else ++ param->value = 0; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int gelicw_set_encodeext(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_point *enc = &wrqu->encoding; ++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; ++ int i, index, key_index; ++ ++ dev_dbg(ntodev(netdev), "wx:set_encodeext\n"); ++ index = enc->flags & IW_ENCODE_INDEX; ++ if (index < 0 || index > WEP_KEYS) ++ return -EINVAL; ++ ++ index--; ++ if (ext->key_len > IW_ENCODING_TOKEN_MAX) ++ return -EINVAL; ++ ++ if (index != -1) ++ w->key_index = index; ++ key_index = w->key_index; ++ ++ if (enc->flags & IW_ENCODE_DISABLED) { ++ /* disable encryption */ ++ if (index == -1) { ++ /* disable all */ ++ w->key_alg = IW_ENCODE_ALG_NONE; ++ for (i = 0; i < WEP_KEYS; i++) ++ w->key_len[i] = 0; ++ } else ++ w->key_len[key_index] = 0; ++ } else if (enc->flags & IW_ENCODE_NOKEY) ++ /* key not changed */ ++ w->key_alg = ext->alg; ++ else { ++ w->key_len[key_index] = ext->key_len; ++ w->key_alg = ext->alg; ++ if (w->key_alg != IW_ENCODE_ALG_NONE && w->key_len[key_index]) ++ memcpy(w->key[key_index], ext->key, w->key_len[key_index]); ++ } ++ dev_dbg(ntodev(netdev), "key %d len:%d alg:%x\n",\ ++ key_index, w->key_len[key_index], w->key_alg); ++ ++ if (w->state >= GELICW_STATE_SCAN_DONE && ++ w->cmd_send_flg == 0 && w->essid_len) ++ /* scan essid and set other params */ ++ schedule_delayed_work(&w->work_scan_essid, 0); ++ else ++ schedule_delayed_work(&w->work_encode, 0); ++ ++ return 0; ++} ++ ++static int gelicw_get_encodeext(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ struct iw_point *enc = &wrqu->encoding; ++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; ++ int index, key_index, key_len; ++ ++ dev_dbg(ntodev(netdev), "wx:get_encodeext\n"); ++ key_len = enc->length - sizeof(*ext); ++ if (key_len < 0) ++ return -EINVAL; ++ ++ index = enc->flags & IW_ENCODE_INDEX; ++ if (index < 0 || index > WEP_KEYS) ++ return -EINVAL; ++ ++ index--; ++ key_index = (index == -1 ? w->key_index : index); ++ ++ memset(ext, 0, sizeof(*ext)); ++ enc->flags = key_index + 1; ++ ++ if (w->key_alg == IW_ENCODE_ALG_NONE || !w->key_len[key_index]) { ++ /* no encryption */ ++ enc->flags |= IW_ENCODE_DISABLED; ++ ext->alg = IW_ENCODE_ALG_NONE; ++ ext->key_len = 0; ++ } else { ++ enc->flags |= IW_ENCODE_NOKEY; ++ ext->alg = w->key_alg; ++ ext->key_len = w->key_len[key_index]; ++ } ++ ++ return 0; ++} ++ ++/* ++ * wireless stats ++ */ ++static struct iw_statistics *gelicw_get_wireless_stats(struct net_device *netdev) ++{ ++ static struct iw_statistics wstats; ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ ++ dev_dbg(ntodev(netdev), "wx:wireless_stats\n"); ++ if (w->state < GELICW_STATE_ASSOCIATED) { ++ wstats.qual.updated = IW_QUAL_QUAL_UPDATED | ++ IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ wstats.qual.qual = 0; ++ wstats.qual.level = 0; ++ return &wstats; ++ } ++ init_completion(&w->rssi_done); ++ schedule_delayed_work(&w->work_rssi, 0); ++ ++ wait_for_completion_interruptible(&w->rssi_done); ++ wstats.qual.updated = IW_QUAL_QUAL_UPDATED | ++ IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; ++ wstats.qual.qual = w->rssi; ++ wstats.qual.level = gelicw_qual2level(w->rssi); ++ ++ return &wstats; ++} ++ ++/* ++ * private handler ++ */ ++static int gelicw_priv_set_alg_mode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ int mode = *(int *)extra; ++ ++ dev_dbg(ntodev(netdev), "wx:priv_set_alg\n"); ++ switch (mode) { ++ case IW_ENCODE_ALG_NONE: ++ case IW_ENCODE_ALG_WEP: ++ case IW_ENCODE_ALG_TKIP: ++ case IW_ENCODE_ALG_CCMP: ++ break; ++ default: ++ return -EINVAL; ++ } ++ /* send common config */ ++ gelicw_send_common_config(netdev, &w->key_alg, (u8)mode); ++ ++ return 0; ++} ++ ++static int gelicw_priv_get_alg_mode(struct net_device *netdev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct gelic_wireless *w = gelicw_priv(netdev); ++ char *p; ++ ++ dev_dbg(ntodev(netdev), "wx:priv_get_alg\n"); ++ switch (w->key_alg) { ++ case IW_ENCODE_ALG_NONE: ++ strncpy(extra, "OFF", MAX_IW_PRIV_SIZE); ++ break; ++ case IW_ENCODE_ALG_WEP: ++ strncpy(extra, "WEP", MAX_IW_PRIV_SIZE); ++ break; ++ case IW_ENCODE_ALG_TKIP: ++ strncpy(extra, "TKIP", MAX_IW_PRIV_SIZE); ++ break; ++ case IW_ENCODE_ALG_CCMP: ++ strncpy(extra, "AES-CCMP", MAX_IW_PRIV_SIZE); ++ break; ++ default: ++ break; ++ } ++ p = extra + strlen(extra); ++ ++ if (w->key_alg == IW_ENCODE_ALG_TKIP || ++ w->key_alg == IW_ENCODE_ALG_CCMP) { ++ if (w->key_len[w->key_index] == 64) /* current key index */ ++ strncpy(p, " hex", MAX_IW_PRIV_SIZE); ++ else ++ strncpy(p, " passphrase", MAX_IW_PRIV_SIZE); ++ } ++ wrqu->data.length = strlen(extra); ++ ++ return 0; ++} ++ ++ ++/* ++ * Wireless handlers ++ */ ++static const iw_handler gelicw_handler[] = ++{ ++ [IW_IOCTL_IDX(SIOCGIWNAME)] = gelicw_get_name, ++ [IW_IOCTL_IDX(SIOCSIWFREQ)] = gelicw_set_freq, ++ [IW_IOCTL_IDX(SIOCGIWFREQ)] = gelicw_get_freq, ++ [IW_IOCTL_IDX(SIOCSIWMODE)] = gelicw_set_mode, ++ [IW_IOCTL_IDX(SIOCGIWMODE)] = gelicw_get_mode, ++ [IW_IOCTL_IDX(SIOCGIWRANGE)] = gelicw_get_range, ++ [IW_IOCTL_IDX(SIOCSIWAP)] = gelicw_set_wap, ++ [IW_IOCTL_IDX(SIOCGIWAP)] = gelicw_get_wap, ++ [IW_IOCTL_IDX(SIOCSIWSCAN)] = gelicw_set_scan, ++ [IW_IOCTL_IDX(SIOCGIWSCAN)] = gelicw_get_scan, ++ [IW_IOCTL_IDX(SIOCSIWESSID)] = gelicw_set_essid, ++ [IW_IOCTL_IDX(SIOCGIWESSID)] = gelicw_get_essid, ++ [IW_IOCTL_IDX(SIOCSIWNICKN)] = gelicw_set_nick, ++ [IW_IOCTL_IDX(SIOCGIWNICKN)] = gelicw_get_nick, ++ [IW_IOCTL_IDX(SIOCSIWRATE)] = gelicw_set_rate, ++ [IW_IOCTL_IDX(SIOCGIWRATE)] = gelicw_get_rate, ++ [IW_IOCTL_IDX(SIOCSIWENCODE)] = gelicw_set_encode, ++ [IW_IOCTL_IDX(SIOCGIWENCODE)] = gelicw_get_encode, ++ [IW_IOCTL_IDX(SIOCSIWAUTH)] = gelicw_set_auth, ++ [IW_IOCTL_IDX(SIOCGIWAUTH)] = gelicw_get_auth, ++ [IW_IOCTL_IDX(SIOCSIWENCODEEXT)] = gelicw_set_encodeext, ++ [IW_IOCTL_IDX(SIOCGIWENCODEEXT)] = gelicw_get_encodeext, ++}; ++ ++/* ++ * Private wireless handlers ++ */ ++enum { ++ GELICW_PRIV_SET_AUTH = SIOCIWFIRSTPRIV, ++ GELICW_PRIV_GET_AUTH ++}; ++ ++static struct iw_priv_args gelicw_private_args[] = { ++ { ++ .cmd = GELICW_PRIV_SET_AUTH, ++ .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ .name = "set_alg" ++ }, ++ { ++ .cmd = GELICW_PRIV_GET_AUTH, ++ .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_IW_PRIV_SIZE, ++ .name = "get_alg" ++ }, ++}; ++ ++static const iw_handler gelicw_private_handler[] = ++{ ++ gelicw_priv_set_alg_mode, ++ gelicw_priv_get_alg_mode, ++}; ++ ++static struct iw_handler_def gelicw_handler_def = ++{ ++ .num_standard = ARRAY_SIZE(gelicw_handler), ++ .num_private = ARRAY_SIZE(gelicw_private_handler), ++ .num_private_args = ARRAY_SIZE(gelicw_private_args), ++ .standard = (iw_handler *)gelicw_handler, ++ .private = (iw_handler *)gelicw_private_handler, ++ .private_args = (struct iw_priv_args *)gelicw_private_args, ++ .get_wireless_stats = gelicw_get_wireless_stats ++}; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/27-powerpc-zimage-signed-types.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/27-powerpc-zimage-signed-types.patch @@ -0,0 +1,23 @@ +Subject: Powerpc: Add signed types to bootwrapper + +Add signed types to the powerpc zImage bootwrapper. These are needed by the +PS3 hcall interface. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/types.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/powerpc/boot/types.h ++++ b/arch/powerpc/boot/types.h +@@ -7,6 +7,10 @@ typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; + typedef unsigned long long u64; ++typedef signed char s8; ++typedef short s16; ++typedef int s32; ++typedef long long s64; + + #define min(x,y) ({ \ + typeof(x) _x = (x); \ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/39-fb_append_extra_logo.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/39-fb_append_extra_logo.patch @@ -0,0 +1,112 @@ +Subject: [PATCH 6/8] fbdev: Add fb_append_extra_logo() + +Add fb_append_extra_logo(), to append extra lines of logos below the standard +Linux logo. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +Acked-By: James Simmons +--- + drivers/video/fbmem.c | 50 +++++++++++++++++++++++++++++++++++++++++---- + include/linux/linux_logo.h | 8 +++++++ + 2 files changed, 54 insertions(+), 4 deletions(-) + +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -318,6 +318,13 @@ static struct logo_data { + const struct linux_logo *logo; + } fb_logo __read_mostly; + ++#define FB_LOGO_EX_NUM_MAX 10 ++static struct logo_data_extra { ++ const struct linux_logo *logo; ++ unsigned int n; ++} fb_logo_ex[FB_LOGO_EX_NUM_MAX]; ++static unsigned int fb_logo_ex_num; ++ + static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) + { + u32 size = width * height, i; +@@ -411,10 +418,22 @@ static void fb_do_show_logo(struct fb_in + } + } + ++#ifdef CONFIG_FB ++void fb_append_extra_logo(const struct linux_logo *logo, unsigned int n) ++{ ++ if (!n || fb_logo_ex_num == FB_LOGO_EX_NUM_MAX) ++ return; ++ ++ fb_logo_ex[fb_logo_ex_num].logo = logo; ++ fb_logo_ex[fb_logo_ex_num].n = n; ++ fb_logo_ex_num++; ++} ++#endif ++ + int fb_prepare_logo(struct fb_info *info, int rotate) + { + int depth = fb_get_color_depth(&info->var, &info->fix); +- int yres; ++ unsigned int yres, height, i; + + memset(&fb_logo, 0, sizeof(struct logo_data)); + +@@ -474,7 +493,21 @@ int fb_prepare_logo(struct fb_info *info + fb_logo.depth = 4; + else + fb_logo.depth = 1; +- return fb_logo.logo->height; ++ ++ /* FIXME: logo_ex supports only truecolor fb. */ ++ if (info->fix.visual != FB_VISUAL_TRUECOLOR) ++ fb_logo_ex_num = 0; ++ ++ height = fb_logo.logo->height; ++ for (i = 0; i < fb_logo_ex_num; i++) { ++ height += fb_logo_ex[i].logo->height; ++ if (height > yres) { ++ height -= fb_logo_ex[i].logo->height; ++ fb_logo_ex_num = i; ++ break; ++ } ++ } ++ return height; + } + + static int fb_show_logo_line(struct fb_info *info, int rotate, +@@ -547,8 +580,17 @@ static int fb_show_logo_line(struct fb_i + + int fb_show_logo(struct fb_info *info, int rotate) + { +- return fb_show_logo_line(info, rotate, fb_logo.logo, 0, +- num_online_cpus()); ++ int y, i; ++ ++ y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, ++ num_online_cpus()); ++ ++ for (i = 0; i < fb_logo_ex_num; i++) { ++ y += fb_show_logo_line(info, rotate, ++ fb_logo_ex[i].logo, y, fb_logo_ex[i].n); ++ } ++ ++ return y; + } + #else + int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } +--- a/include/linux/linux_logo.h ++++ b/include/linux/linux_logo.h +@@ -46,5 +46,13 @@ extern const struct linux_logo logo_supe + extern const struct linux_logo logo_m32r_clut224; + + extern const struct linux_logo *fb_find_logo(int depth); ++#if defined(CONFIG_LOGO) && defined(CONFIG_FB) ++extern void fb_append_extra_logo(const struct linux_logo *logo, ++ unsigned int n); ++#else ++static inline void fb_append_extra_logo(const struct linux_logo *logo, ++ unsigned int n) ++{} ++#endif + + #endif /* _LINUX_LINUX_LOGO_H */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/21-ps3-device-init.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/21-ps3-device-init.patch @@ -0,0 +1,810 @@ +Subject: PS3: Device registration routines. + +Add routines to probe devices present on the system +and to register those devices with the LDM. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/Makefile | 1 + arch/powerpc/platforms/ps3/device-init.c | 789 +++++++++++++++++++++++++++++++ + 2 files changed, 790 insertions(+) + +--- a/arch/powerpc/platforms/ps3/Makefile ++++ b/arch/powerpc/platforms/ps3/Makefile +@@ -4,3 +4,4 @@ obj-y += system-bus.o + + obj-$(CONFIG_SMP) += smp.o + obj-$(CONFIG_SPU_BASE) += spu.o ++obj-y += device-init.o +--- /dev/null ++++ b/arch/powerpc/platforms/ps3/device-init.c +@@ -0,0 +1,789 @@ ++/* ++ * PS3 device registration routines. ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "platform.h" ++ ++/** ++ * ps3_setup_gelic_device - Setup and register a gelic device instance. ++ * ++ * Allocates memory for a struct ps3_system_bus_device instance, initialises the ++ * structure members, and registers the device instance with the system bus. ++ */ ++ ++static int __devinit ps3_setup_gelic_device( ++ const struct ps3_repository_device *repo) ++{ ++ int result; ++ struct layout { ++ struct ps3_system_bus_device dev; ++ struct ps3_dma_region d_region; ++ } *p; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB); ++ BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC); ++ ++ p = kzalloc(sizeof(struct layout), GFP_KERNEL); ++ ++ if (!p) { ++ result = -ENOMEM; ++ goto fail_malloc; ++ } ++ ++ p->dev.match_id = PS3_MATCH_ID_GELIC; ++ p->dev.dev_type = PS3_DEVICE_TYPE_SB; ++ p->dev.bus_id = repo->bus_id; ++ p->dev.dev_id = repo->dev_id; ++ p->dev.d_region = &p->d_region; ++ ++ result = ps3_repository_find_interrupt(repo, ++ PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_repository_find_interrupt failed\n", ++ __func__, __LINE__); ++ goto fail_find_interrupt; ++ } ++ ++ BUG_ON(p->dev.interrupt_id != 0); ++ ++ result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K, ++ PS3_DMA_OTHER, NULL, 0); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_dma_region_init failed\n", ++ __func__, __LINE__); ++ goto fail_dma_init; ++ } ++ ++ result = ps3_system_bus_device_register(&p->dev); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ goto fail_device_register; ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++ ++fail_device_register: ++fail_dma_init: ++fail_find_interrupt: ++ kfree(p); ++fail_malloc: ++ pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __devinit ps3_setup_uhc_device( ++ const struct ps3_repository_device *repo, enum ps3_match_id match_id, ++ enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type) ++{ ++ int result; ++ struct layout { ++ struct ps3_system_bus_device dev; ++ struct ps3_dma_region d_region; ++ struct ps3_mmio_region m_region; ++ } *p; ++ u64 bus_addr; ++ u64 len; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB); ++ BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB); ++ ++ p = kzalloc(sizeof(struct layout), GFP_KERNEL); ++ ++ if (!p) { ++ result = -ENOMEM; ++ goto fail_malloc; ++ } ++ ++ p->dev.match_id = match_id; ++ p->dev.dev_type = PS3_DEVICE_TYPE_SB; ++ p->dev.bus_id = repo->bus_id; ++ p->dev.dev_id = repo->dev_id; ++ p->dev.d_region = &p->d_region; ++ p->dev.m_region = &p->m_region; ++ ++ result = ps3_repository_find_interrupt(repo, ++ interrupt_type, &p->dev.interrupt_id); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_repository_find_interrupt failed\n", ++ __func__, __LINE__); ++ goto fail_find_interrupt; ++ } ++ ++ result = ps3_repository_find_reg(repo, reg_type, ++ &bus_addr, &len); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_repository_find_reg failed\n", ++ __func__, __LINE__); ++ goto fail_find_reg; ++ } ++ ++ result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K, ++ PS3_DMA_INTERNAL, NULL, 0); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_dma_region_init failed\n", ++ __func__, __LINE__); ++ goto fail_dma_init; ++ } ++ ++ result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len, ++ PS3_MMIO_4K); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_mmio_region_init failed\n", ++ __func__, __LINE__); ++ goto fail_mmio_init; ++ } ++ ++ result = ps3_system_bus_device_register(&p->dev); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ goto fail_device_register; ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++ ++fail_device_register: ++fail_mmio_init: ++fail_dma_init: ++fail_find_reg: ++fail_find_interrupt: ++ kfree(p); ++fail_malloc: ++ pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __devinit ps3_setup_ehci_device( ++ const struct ps3_repository_device *repo) ++{ ++ return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI, ++ PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI); ++} ++ ++static int __devinit ps3_setup_ohci_device( ++ const struct ps3_repository_device *repo) ++{ ++ return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI, ++ PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI); ++} ++ ++static int __devinit ps3_setup_vuart_device(enum ps3_match_id match_id, ++ unsigned int port_number) ++{ ++ int result; ++ struct layout { ++ struct ps3_system_bus_device dev; ++ } *p; ++ ++ pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__, ++ match_id, port_number); ++ ++ p = kzalloc(sizeof(struct layout), GFP_KERNEL); ++ ++ if (!p) ++ return -ENOMEM; ++ ++ p->dev.match_id = match_id; ++ p->dev.dev_type = PS3_DEVICE_TYPE_VUART; ++ p->dev.port_number = port_number; ++ ++ result = ps3_system_bus_device_register(&p->dev); ++ ++ if (result) ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, ++ unsigned int timeout) ++{ ++ int result = -1; ++ unsigned int retries = 0; ++ u64 status; ++ ++ for (retries = 0; retries < timeout; retries++) { ++ result = lv1_storage_check_async_status(dev_id, tag, &status); ++ if (!result) ++ break; ++ ++ msleep(1); ++ } ++ ++ if (result) ++ pr_debug("%s:%u: check_async_status: %s, status %lx\n", ++ __func__, __LINE__, ps3_result(result), status); ++ ++ return result; ++} ++ ++/** ++ * ps3_storage_wait_for_device - Wait for a storage device to become ready. ++ * @repo: The repository device to wait for. ++ * ++ * Uses the hypervisor's storage device notification mechanism to wait until ++ * a storage device is ready. The device notification mechanism uses a ++ * psuedo device (id = -1) to asynchronously notify the guest when storage ++ * devices become ready. The notification device has a block size of 512 ++ * bytes. ++ */ ++ ++static int ps3_storage_wait_for_device( ++ const struct ps3_repository_device *repo) ++{ ++ int result; ++ const u64 notification_dev_id = (u64)-1LL; ++ const unsigned int timeout = HZ; ++ u64 lpar; ++ u64 tag; ++ struct { ++ u64 operation_code; /* must be zero */ ++ u64 event_mask; /* 1 = device ready */ ++ } *notify_cmd; ++ struct { ++ u64 event_type; /* notify_device_ready */ ++ u64 bus_id; ++ u64 dev_id; ++ u64 dev_type; ++ u64 dev_port; ++ } *notify_event; ++ enum {notify_device_ready = 1,}; ++ ++ pr_info(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__, ++ __LINE__, repo->bus_id, repo->dev_id, repo->dev_type); ++ ++ notify_cmd = kzalloc(512, GFP_KERNEL); ++ notify_event = (void*)notify_cmd; ++ ++ if (!notify_cmd) ++ return -ENOMEM; ++ ++ lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd)); ++ ++ result = lv1_open_device(repo->bus_id, notification_dev_id, 0); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ result = -ENODEV; ++ goto fail_free; ++ } ++ ++ /* Setup and write the request for device notification. */ ++ ++ notify_cmd->operation_code = 0; /* must be zero */ ++ notify_cmd->event_mask = 0x01; /* device ready */ ++ ++ result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, &tag); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, ++ ps3_result(result)); ++ result = -ENODEV; ++ goto fail_close; ++ } ++ ++ /* Wait for the write completion */ ++ ++ result = ps3stor_wait_for_completion(notification_dev_id, tag, timeout); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ result = -ENODEV; ++ goto fail_close; ++ } ++ ++ /* Loop here processing the requested notification events. */ ++ ++ result = -ENODEV; ++ while (1) { ++ memset(notify_event, 0, sizeof(*notify_event)); ++ ++ result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0, lpar, ++ &tag); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: write failed %s\n", __func__, ++ __LINE__, ps3_result(result)); ++ break; ++ } ++ ++ result = ps3stor_wait_for_completion(notification_dev_id, tag, ++ timeout); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: read not completed %s\n", ++ __func__, __LINE__, ps3_result(result)); ++ break; ++ } ++ ++ if (notify_event->event_type != notify_device_ready ++ || notify_event->bus_id != repo->bus_id) { ++ pr_debug("%s:%u: bad notify_event: event %lu, " ++ "dev_id %lu, dev_type %lu\n", __func__, ++ __LINE__, notify_event->event_type, ++ notify_event->dev_id, notify_event->dev_type); ++ break; ++ } ++ ++ if (notify_event->dev_id == repo->dev_id ++ && notify_event->dev_type == repo->dev_type) { ++ pr_debug("%s:%u: device ready: dev_id %u\n", __func__, ++ __LINE__, repo->dev_id); ++ result = 0; ++ break; ++ } ++ ++ if (notify_event->dev_id == repo->dev_id ++ && notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) { ++ pr_debug("%s:%u: no access: dev_id %u\n", __func__, ++ __LINE__, repo->dev_id); ++ break; ++ } ++ } ++ ++fail_close: ++ lv1_close_device(repo->bus_id, notification_dev_id); ++fail_free: ++ kfree(notify_cmd); ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __devinit ps3_setup_storage_dev( ++ const struct ps3_repository_device *repo, enum ps3_match_id match_id) ++{ ++ int result; ++ struct ps3_storage_device *p; ++ u64 port, blk_size, num_blocks; ++ unsigned int num_regions, i; ++ ++ pr_debug(" -> %s:%d: match_id %u\n", __func__, __LINE__, match_id); ++ ++ result = ps3_repository_read_stor_dev_info(repo->bus_index, ++ repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n", ++ __func__, __LINE__, result); ++ return -ENODEV; ++ } ++ ++ pr_debug("%s:%u: index %u:%u: port %lu blk_size %lu num_blocks %lu " ++ "num_regions %u\n", __func__, __LINE__, repo->bus_index, ++ repo->dev_index, port, blk_size, num_blocks, num_regions); ++ ++ p = kzalloc(sizeof(struct ps3_storage_device) + ++ num_regions * sizeof(struct ps3_storage_region), GFP_KERNEL); ++ ++ if (!p) { ++ result = -ENOMEM; ++ goto fail_malloc; ++ } ++ ++ p->sbd.match_id = match_id; ++ p->sbd.dev_type = PS3_DEVICE_TYPE_SB; ++ p->sbd.bus_id = repo->bus_id; ++ p->sbd.dev_id = repo->dev_id; ++ p->sbd.d_region = &p->dma_region; ++ p->blk_size = blk_size; ++ p->num_regions = num_regions; ++ ++ result = ps3_repository_find_interrupt(repo, ++ PS3_INTERRUPT_TYPE_EVENT_PORT, &p->sbd.interrupt_id); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__, ++ __LINE__, result); ++ result = -ENODEV; ++ goto fail_find_interrupt; ++ } ++ ++ /* FIXME: Arrange to only do this on a 'cold' boot */ ++ ++ result = ps3_storage_wait_for_device(repo); ++ ++ if (result) { ++ printk(KERN_ERR "%s:%u: storage_notification failed %d\n", ++ __func__, __LINE__, result); ++ result = -ENODEV; ++ goto fail_probe_notification; ++ } ++ ++ for (i = 0; i < num_regions; i++) { ++ unsigned int id; ++ u64 start, size; ++ ++ result = ps3_repository_read_stor_dev_region(repo->bus_index, ++ repo->dev_index, i, &id, &start, &size); ++ ++ if (result) { ++ printk(KERN_ERR ++ "%s:%u: read_stor_dev_region failed %d\n", ++ __func__, __LINE__, result); ++ result = -ENODEV; ++ goto fail_read_region; ++ } ++ pr_debug("%s:%u: region %u: id %u start %lu size %lu\n", ++ __func__, __LINE__, i, id, start, size); ++ ++ p->regions[i].id = id; ++ p->regions[i].start = start; ++ p->regions[i].size = size; ++ } ++ ++ result = ps3_system_bus_device_register(&p->sbd); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ goto fail_device_register; ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return 0; ++ ++fail_device_register: ++fail_read_region: ++fail_probe_notification: ++fail_find_interrupt: ++ kfree(p); ++fail_malloc: ++ pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __init ps3_register_vuart_devices(void) ++{ ++ int result; ++ unsigned int port_number; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ result = ps3_repository_read_vuart_av_port(&port_number); ++ if (result) ++ port_number = 0; /* av default */ ++ ++ result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number); ++ WARN_ON(result); ++ ++ result = ps3_repository_read_vuart_sysmgr_port(&port_number); ++ if (result) ++ port_number = 2; /* sysmgr default */ ++ ++ result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER, ++ port_number); ++ WARN_ON(result); ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __init ps3_register_sound_devices(void) ++{ ++ int result; ++ struct layout { ++ struct ps3_system_bus_device dev; ++ struct ps3_dma_region d_region; ++ struct ps3_mmio_region m_region; ++ } *p; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ p = kzalloc(sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ ++ p->dev.match_id = PS3_MATCH_ID_SOUND; ++ p->dev.dev_type = PS3_DEVICE_TYPE_IOC0; ++ p->dev.d_region = &p->d_region; ++ p->dev.m_region = &p->m_region; ++ ++ result = ps3_system_bus_device_register(&p->dev); ++ ++ if (result) ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int __devinit ps3_register_graphics_devices(void) ++{ ++ int result; ++ struct layout { ++ struct ps3_system_bus_device dev; ++ } *p; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ p = kzalloc(sizeof(struct layout), GFP_KERNEL); ++ ++ if (!p) ++ return -ENOMEM; ++ ++ p->dev.match_id = PS3_MATCH_ID_GRAPHICS; ++ p->dev.dev_type = PS3_DEVICE_TYPE_IOC0; ++ ++ result = ps3_system_bus_device_register(&p->dev); ++ ++ if (result) ++ pr_debug("%s:%d ps3_system_bus_device_register failed\n", ++ __func__, __LINE__); ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++/** ++ * ps3_register_repository_device - Register a device from the repositiory info. ++ * ++ */ ++ ++static int __devinit ps3_register_repository_device( ++ const struct ps3_repository_device *repo) ++{ ++ int result; ++ ++ switch(repo->dev_type) { ++ case PS3_DEV_TYPE_SB_GELIC: ++ result = ps3_setup_gelic_device(repo); ++ if (result) { ++ pr_debug("%s:%d ps3_setup_gelic_device failed\n", ++ __func__, __LINE__); ++ } ++ break; ++ case PS3_DEV_TYPE_SB_USB: ++ ++ /* Each USB device has both an EHCI and an OHCI HC */ ++ ++ result = ps3_setup_ehci_device(repo); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_setup_ehci_device failed\n", ++ __func__, __LINE__); ++ } ++ ++ result = ps3_setup_ohci_device(repo); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_setup_ohci_device failed\n", ++ __func__, __LINE__); ++ } ++ break; ++ case PS3_DEV_TYPE_STOR_DISK: ++ result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK); ++ ++ /* Some devices are not accessable from the Other OS lpar. */ ++ ++ if (result == -ENODEV) { ++ result = 0; ++ pr_debug("%s:%d: not accessable\n", ++ __func__, __LINE__); ++ } ++ ++ if (result) { ++ pr_debug("%s:%d ps3_setup_storage_dev failed\n", ++ __func__, __LINE__); ++ } ++ break; ++ case PS3_DEV_TYPE_STOR_ROM: ++ result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM); ++ if (result) { ++ pr_debug("%s:%d ps3_setup_storage_dev failed\n", ++ __func__, __LINE__); ++ } ++ break; ++ case PS3_DEV_TYPE_STOR_FLASH: ++ result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH); ++ if (result) { ++ pr_debug("%s:%d ps3_setup_storage_dev failed\n", ++ __func__, __LINE__); ++ } ++ break; ++ default: ++ result = 0; ++ pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__, ++ repo->dev_type); ++ } ++ ++ return result; ++} ++ ++/** ++ * ps3_probe_thread - Background repository probing at system startup. ++ * ++ * This implementation only supports background probing on a single bus. ++ */ ++ ++static int ps3_probe_thread(void *data) ++{ ++ struct ps3_repository_device *repo = data; ++ int result; ++ unsigned int ms = 250; ++ ++ pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); ++ ++ do { ++ try_to_freeze(); ++ ++ pr_debug("%s:%u: probing...\n", __func__, __LINE__); ++ ++ do { ++ result = ps3_repository_find_device(repo); ++ ++ if (result == -ENODEV) ++ pr_debug("%s:%u: nothing new\n", __func__, ++ __LINE__); ++ else if (result) ++ pr_debug("%s:%u: find device error.\n", ++ __func__, __LINE__); ++ else { ++ pr_debug("%s:%u: found device\n", __func__, ++ __LINE__); ++ ps3_register_repository_device(repo); ++ ps3_repository_bump_device(repo); ++ ms = 250; ++ } ++ } while (!result); ++ ++ pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms); ++ ++ if ( ms > 60000) ++ break; ++ ++ msleep_interruptible(ms); ++ ++ /* An exponential backoff. */ ++ ms <<= 1; ++ ++ } while (!kthread_should_stop()); ++ ++ pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__); ++ ++ return 0; ++} ++ ++/** ++ * ps3_start_probe_thread - Starts the background probe thread. ++ * ++ */ ++ ++static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type) ++{ ++ int result; ++ struct task_struct *task; ++ static struct ps3_repository_device repo; /* must be static */ ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ memset(&repo, 0, sizeof(repo)); ++ ++ repo.bus_type = bus_type; ++ ++ result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); ++ ++ if (result) { ++ printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result); ++ return -ENODEV; ++ } ++ ++ result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); ++ ++ if (result) { ++ printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__, ++ result); ++ return -ENODEV; ++ } ++ ++ task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type); ++ ++ if (IS_ERR(task)) { ++ result = PTR_ERR(task); ++ printk(KERN_ERR "%s: kthread_run failed %d\n", __func__, ++ result); ++ return result; ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return 0; ++} ++ ++/** ++ * ps3_register_devices - Probe the system and register devices found. ++ * ++ * A device_initcall() routine. ++ */ ++ ++static int __init ps3_register_devices(void) ++{ ++ int result; ++ ++ if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) ++ return -ENODEV; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ /* ps3_repository_dump_bus_info(); */ ++ ++ result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE); ++ ++ ps3_register_vuart_devices(); ++ ++ ps3_register_graphics_devices(); ++ ++ ps3_repository_find_devices(PS3_BUS_TYPE_SB, ++ ps3_register_repository_device); ++ ++ ps3_register_sound_devices(); ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return 0; ++} ++ ++device_initcall(ps3_register_devices); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/06-ps3av-hdmi-rgb-range.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/06-ps3av-hdmi-rgb-range.patch @@ -0,0 +1,96 @@ +Subject: PS3: Add support for HDMI RGB Full Range mode +From: Masashi Kimoto + +Add support for HDMI RGB Full Range mode, which is available on system +software 1.80 or newer. + +CC: Masashi Kimoto +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + drivers/ps3/ps3av_cmd.c | 16 ++++++++++++++++ + include/asm-powerpc/ps3av.h | 12 +++++++++--- + 2 files changed, 25 insertions(+), 3 deletions(-) + +--- a/drivers/ps3/ps3av_cmd.c ++++ b/drivers/ps3/ps3av_cmd.c +@@ -143,6 +143,14 @@ static u32 ps3av_vid_video2av(int vid) + return PS3AV_CMD_AV_VID_480P; + } + ++static int ps3av_hdmi_range(void) ++{ ++ if (ps3_compare_firmware_version(1, 8, 0) < 0) ++ return 0; ++ else ++ return 1; /* supported */ ++} ++ + int ps3av_cmd_init(void) + { + int res; +@@ -350,6 +358,10 @@ u32 ps3av_cmd_set_av_video_cs(void *p, u + /* should be same as video_mode.video_cs_out */ + av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8); + av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out); ++ if ((id & PS3AV_MODE_WHITE) && ps3av_hdmi_range()) ++ av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_ON; ++ else /* default off */ ++ av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_OFF; + av_video_cs->aspect = aspect; + if (id & PS3AV_MODE_DITHER) { + av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON +@@ -392,6 +404,10 @@ u32 ps3av_cmd_set_video_mode(void *p, u3 + video_mode->pitch = video_mode->width * 4; /* line_length */ + video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT; + video_mode->video_format = ps3av_video_fmt_table[video_fmt].format; ++ if ((id & PS3AV_MODE_COLOR) && ps3av_hdmi_range()) ++ video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT; ++ else /* default enable */ ++ video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT; + video_mode->video_order = ps3av_video_fmt_table[video_fmt].order; + + pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n", +--- a/include/asm-powerpc/ps3av.h ++++ b/include/asm-powerpc/ps3av.h +@@ -159,6 +159,9 @@ + #define PS3AV_CMD_VIDEO_FMT_X8R8G8B8 0x0000 + /* video_out_format */ + #define PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT 0x0000 ++/* video_cl_cnv */ ++#define PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT 0x0000 ++#define PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT 0x0010 + /* video_sync */ + #define PS3AV_CMD_VIDEO_SYNC_VSYNC 0x0001 + #define PS3AV_CMD_VIDEO_SYNC_CSYNC 0x0004 +@@ -311,6 +314,8 @@ + #define PS3AV_MODE_MASK 0x000F + #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */ + #define PS3AV_MODE_DITHER 0x0800 ++#define PS3AV_MODE_COLOR 0x0400 ++#define PS3AV_MODE_WHITE 0x0200 + #define PS3AV_MODE_FULL 0x0080 + #define PS3AV_MODE_DVI 0x0040 + #define PS3AV_MODE_RGB 0x0020 +@@ -529,9 +534,9 @@ struct ps3av_pkt_video_mode { + u32 video_out_format; /* in: out format */ + u32 video_format; /* in: input frame buffer format */ + u8 reserved3; +- u8 reserved4; ++ u8 video_cl_cnv; /* in: color conversion */ + u16 video_order; /* in: input RGB order */ +- u32 reserved5; ++ u32 reserved4; + }; + + /* video: format */ +@@ -539,7 +544,8 @@ struct ps3av_pkt_video_format { + struct ps3av_send_hdr send_hdr; + u32 video_head; /* in: head */ + u32 video_format; /* in: frame buffer format */ +- u16 reserved; ++ u8 reserved; ++ u8 video_cl_cnv; /* in: color conversion */ + u16 video_order; /* in: input RGB order */ + }; + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/14-ps3-repository-probe-cleanups.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/14-ps3-repository-probe-cleanups.patch @@ -0,0 +1,773 @@ +Subject: PS3: Repository probe cleanups + +Repository updates: + - Extract ps3_repository_find_bus() from ps3_repository_find_device(), as the + storage driver needs it. + - Make ps3_repository_find_device() return -ENODEV if a device is not found, + just like if a bus is not found. + - Add ps3_repository_read_vuart_sysmgr_port() and + ps3_repository_read_vuart_av_port() to get vuart port info. + - Add device enumeration routines ps3_repository_find_device() and + ps3_repository_find_devices(). + - Cleanup debug routines. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/platform.h | 31 + + arch/powerpc/platforms/ps3/repository.c | 592 +++++++++++++++++--------------- + 2 files changed, 340 insertions(+), 283 deletions(-) + +--- a/arch/powerpc/platforms/ps3/platform.h ++++ b/arch/powerpc/platforms/ps3/platform.h +@@ -130,24 +130,28 @@ int ps3_repository_read_dev_reg(unsigned + /* repository bus enumerators */ + + struct ps3_repository_device { ++ enum ps3_bus_type bus_type; + unsigned int bus_index; ++ unsigned int bus_id; ++ enum ps3_dev_type dev_type; + unsigned int dev_index; +- struct ps3_device_id did; ++ unsigned int dev_id; + }; + +-int ps3_repository_find_device(enum ps3_bus_type bus_type, +- enum ps3_dev_type dev_type, +- const struct ps3_repository_device *start_dev, +- struct ps3_repository_device *dev); +-static inline int ps3_repository_find_first_device( +- enum ps3_bus_type bus_type, enum ps3_dev_type dev_type, +- struct ps3_repository_device *dev) ++static inline struct ps3_repository_device *ps3_repository_bump_device( ++ struct ps3_repository_device *repo) + { +- return ps3_repository_find_device(bus_type, dev_type, NULL, dev); ++ repo->dev_index++; ++ return repo; + } +-int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, ++int ps3_repository_find_device(struct ps3_repository_device *repo); ++int ps3_repository_find_devices(enum ps3_bus_type bus_type, ++ int (*callback)(const struct ps3_repository_device *repo)); ++int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, ++ unsigned int *bus_index); ++int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, + enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); +-int ps3_repository_find_reg(const struct ps3_repository_device *dev, ++int ps3_repository_find_reg(const struct ps3_repository_device *repo, + enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); + + /* repository block device info */ +@@ -217,6 +221,11 @@ int ps3_repository_read_num_spu_resource + int ps3_repository_read_spu_resource_id(unsigned int res_index, + enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); + ++/* repository vuart info */ ++ ++int ps3_repository_read_vuart_av_port(unsigned int *port); ++int ps3_repository_read_vuart_sysmgr_port(unsigned int *port); ++ + /* Page table entries */ + #define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ + #define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ +--- a/arch/powerpc/platforms/ps3/repository.c ++++ b/arch/powerpc/platforms/ps3/repository.c +@@ -138,7 +138,7 @@ static int read_node(unsigned int lpar_i + pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", + __func__, __LINE__, ps3_result(result)); + dump_node_name(lpar_id, n1, n2, n3, n4); +- return result; ++ return -ENOENT; + } + + dump_node(lpar_id, n1, n2, n3, n4, v1, v2); +@@ -155,7 +155,7 @@ static int read_node(unsigned int lpar_i + pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", + __func__, __LINE__, v2); + +- return result; ++ return 0; + } + + int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, +@@ -314,324 +314,140 @@ int ps3_repository_read_dev_reg(unsigned + reg_index, bus_addr, len); + } + +-#if defined(DEBUG) +-int ps3_repository_dump_resource_info(unsigned int bus_index, +- unsigned int dev_index) +-{ +- int result = 0; +- unsigned int res_index; + +- pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, +- bus_index, dev_index); + +- for (res_index = 0; res_index < 10; res_index++) { +- enum ps3_interrupt_type intr_type; +- unsigned int interrupt_id; ++int ps3_repository_find_device(struct ps3_repository_device *repo) ++{ ++ int result; ++ struct ps3_repository_device tmp = *repo; ++ unsigned int num_dev; + +- result = ps3_repository_read_dev_intr(bus_index, dev_index, +- res_index, &intr_type, &interrupt_id); ++ BUG_ON(repo->bus_index > 10); ++ BUG_ON(repo->dev_index > 10); + +- if (result) { +- if (result != LV1_NO_ENTRY) +- pr_debug("%s:%d ps3_repository_read_dev_intr" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- break; +- } ++ result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); + +- pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", +- __func__, __LINE__, bus_index, dev_index, intr_type, +- interrupt_id); ++ if (result) { ++ pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); ++ return result; + } + +- for (res_index = 0; res_index < 10; res_index++) { +- enum ps3_reg_type reg_type; +- u64 bus_addr; +- u64 len; +- +- result = ps3_repository_read_dev_reg(bus_index, dev_index, +- res_index, ®_type, &bus_addr, &len); ++ pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n", ++ __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, ++ num_dev); + +- if (result) { +- if (result != LV1_NO_ENTRY) +- pr_debug("%s:%d ps3_repository_read_dev_reg" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- break; +- } +- +- pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", +- __func__, __LINE__, bus_index, dev_index, reg_type, +- bus_addr, len); ++ if (tmp.dev_index >= num_dev) { ++ pr_debug("%s:%d: no device found\n", __func__, __LINE__); ++ return -ENODEV; + } + +- pr_debug(" <- %s:%d\n", __func__, __LINE__); +- return result; +-} ++ result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, ++ &tmp.dev_type); + +-static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index) +-{ +- int result = 0; +- unsigned int num_regions, region_index; +- u64 port, blk_size, num_blocks; +- +- pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, +- bus_index, dev_index); +- +- result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port, +- &blk_size, &num_blocks, &num_regions); + if (result) { +- pr_debug("%s:%d ps3_repository_read_stor_dev_info" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- goto out; ++ pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__); ++ return result; + } + +- pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " +- "%lu, num_regions %u\n", +- __func__, __LINE__, bus_index, dev_index, port, +- blk_size, num_blocks, num_regions); +- +- for (region_index = 0; region_index < num_regions; region_index++) { +- unsigned int region_id; +- u64 region_start, region_size; +- +- result = ps3_repository_read_stor_dev_region(bus_index, +- dev_index, region_index, ®ion_id, ®ion_start, +- ®ion_size); +- if (result) { +- pr_debug("%s:%d ps3_repository_read_stor_dev_region" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- break; +- } ++ result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, ++ &tmp.dev_id); + +- pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", +- __func__, __LINE__, bus_index, dev_index, region_id, +- region_start, region_size); ++ if (result) { ++ pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, ++ __LINE__); ++ return result; + } + +-out: +- pr_debug(" <- %s:%d\n", __func__, __LINE__); +- return result; +-} +- +-static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type, +- unsigned int num_dev) +-{ +- int result = 0; +- unsigned int dev_index; +- +- pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index); +- +- for (dev_index = 0; dev_index < num_dev; dev_index++) { +- enum ps3_dev_type dev_type; +- unsigned int dev_id; +- +- result = ps3_repository_read_dev_type(bus_index, dev_index, +- &dev_type); +- +- if (result) { +- pr_debug("%s:%d ps3_repository_read_dev_type" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- break; +- } +- +- result = ps3_repository_read_dev_id(bus_index, dev_index, +- &dev_id); +- +- if (result) { +- pr_debug("%s:%d ps3_repository_read_dev_id" +- " (%u:%u) failed\n", __func__, __LINE__, +- bus_index, dev_index); +- continue; +- } ++ pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n", ++ __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); + +- pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, +- __LINE__, bus_index, dev_index, dev_type, dev_id); +- +- ps3_repository_dump_resource_info(bus_index, dev_index); +- +- if (bus_type == PS3_BUS_TYPE_STORAGE) +- dump_stor_dev_info(bus_index, dev_index); +- } +- +- pr_debug(" <- %s:%d\n", __func__, __LINE__); +- return result; ++ *repo = tmp; ++ return 0; + } + +-int ps3_repository_dump_bus_info(void) ++int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, ++ int (*callback)(const struct ps3_repository_device *repo)) + { + int result = 0; +- unsigned int bus_index; ++ struct ps3_repository_device repo; + +- pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); + +- for (bus_index = 0; bus_index < 10; bus_index++) { +- enum ps3_bus_type bus_type; +- unsigned int bus_id; +- unsigned int num_dev; ++ for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { + +- result = ps3_repository_read_bus_type(bus_index, &bus_type); ++ result = ps3_repository_read_bus_type(repo.bus_index, ++ &repo.bus_type); + + if (result) { + pr_debug("%s:%d read_bus_type(%u) failed\n", +- __func__, __LINE__, bus_index); ++ __func__, __LINE__, repo.bus_index); + break; + } + +- result = ps3_repository_read_bus_id(bus_index, &bus_id); +- +- if (result) { +- pr_debug("%s:%d read_bus_id(%u) failed\n", +- __func__, __LINE__, bus_index); ++ if (repo.bus_type != bus_type) { ++ pr_debug("%s:%d: skip, bus_type %u\n", __func__, ++ __LINE__, repo.bus_type); + continue; + } + +- if (bus_index != bus_id) +- pr_debug("%s:%d bus_index != bus_id\n", +- __func__, __LINE__); +- +- result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); ++ result = ps3_repository_read_bus_id(repo.bus_index, ++ &repo.bus_id); + + if (result) { +- pr_debug("%s:%d read_bus_num_dev(%u) failed\n", +- __func__, __LINE__, bus_index); ++ pr_debug("%s:%d read_bus_id(%u) failed\n", ++ __func__, __LINE__, repo.bus_index); + continue; + } + +- pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", +- __func__, __LINE__, bus_index, bus_type, bus_id, +- num_dev); +- +- dump_device_info(bus_index, bus_type, num_dev); +- } ++ for (repo.dev_index = 0; ; repo.dev_index++) { ++ result = ps3_repository_find_device(&repo); + +- pr_debug(" <- %s:%d\n", __func__, __LINE__); +- return result; +-} +-#endif /* defined(DEBUG) */ +- +-static int find_device(unsigned int bus_index, unsigned int num_dev, +- unsigned int start_dev_index, enum ps3_dev_type dev_type, +- struct ps3_repository_device *dev) +-{ +- int result = 0; +- unsigned int dev_index; +- +- pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); +- +- dev->dev_index = UINT_MAX; +- +- for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { +- enum ps3_dev_type x; +- +- result = ps3_repository_read_dev_type(bus_index, dev_index, +- &x); +- +- if (result) { +- pr_debug("%s:%d read_dev_type failed\n", +- __func__, __LINE__); +- return result; ++ if(result == -ENODEV) { ++ result = 0; ++ break; ++ } else if(result) ++ break; ++ ++ result = callback(&repo); ++ ++ if (result) { ++ pr_debug("%s:%d: abort at callback\n", __func__, ++ __LINE__); ++ break; ++ } + } +- +- if (x == dev_type) +- break; ++ break; + } + +- if (dev_index == num_dev) +- return -1; +- +- pr_debug("%s:%d: found dev_type %u at dev_index %u\n", +- __func__, __LINE__, dev_type, dev_index); +- +- result = ps3_repository_read_dev_id(bus_index, dev_index, +- &dev->did.dev_id); +- +- if (result) { +- pr_debug("%s:%d read_dev_id failed\n", +- __func__, __LINE__); +- return result; +- } +- +- dev->dev_index = dev_index; +- +- pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__, +- dev->did.dev_id); +- ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; + } + +-int ps3_repository_find_device (enum ps3_bus_type bus_type, +- enum ps3_dev_type dev_type, +- const struct ps3_repository_device *start_dev, +- struct ps3_repository_device *dev) ++int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, ++ unsigned int *bus_index) + { +- int result = 0; +- unsigned int bus_index; +- unsigned int num_dev; +- +- pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, +- bus_type, dev_type); +- +- BUG_ON(start_dev && start_dev->bus_index > 10); +- +- for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; +- bus_index++) { +- enum ps3_bus_type x; +- +- result = ps3_repository_read_bus_type(bus_index, &x); ++ unsigned int i; ++ enum ps3_bus_type type; ++ int error; + +- if (result) { ++ for (i = from; i < 10; i++) { ++ error = ps3_repository_read_bus_type(i, &type); ++ if (error) { + pr_debug("%s:%d read_bus_type failed\n", + __func__, __LINE__); +- dev->bus_index = UINT_MAX; +- return result; ++ *bus_index = UINT_MAX; ++ return error; ++ } ++ if (type == bus_type) { ++ *bus_index = i; ++ return 0; + } +- if (x == bus_type) +- break; +- } +- +- if (bus_index >= 10) +- return -ENODEV; +- +- pr_debug("%s:%d: found bus_type %u at bus_index %u\n", +- __func__, __LINE__, bus_type, bus_index); +- +- result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); +- +- if (result) { +- pr_debug("%s:%d read_bus_num_dev failed\n", +- __func__, __LINE__); +- return result; +- } +- +- result = find_device(bus_index, num_dev, start_dev +- ? start_dev->dev_index + 1 : 0, dev_type, dev); +- +- if (result) { +- pr_debug("%s:%d get_did failed\n", __func__, __LINE__); +- return result; +- } +- +- result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id); +- +- if (result) { +- pr_debug("%s:%d read_bus_id failed\n", +- __func__, __LINE__); +- return result; + } +- +- dev->bus_index = bus_index; +- +- pr_debug("%s:%d found: bus_id %u, dev_id %u\n", +- __func__, __LINE__, dev->did.bus_id, dev->did.dev_id); +- +- return result; ++ *bus_index = UINT_MAX; ++ return -ENODEV; + } + +-int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, ++int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, + enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) + { + int result = 0; +@@ -645,8 +461,8 @@ int ps3_repository_find_interrupt(const + enum ps3_interrupt_type t; + unsigned int id; + +- result = ps3_repository_read_dev_intr(dev->bus_index, +- dev->dev_index, res_index, &t, &id); ++ result = ps3_repository_read_dev_intr(repo->bus_index, ++ repo->dev_index, res_index, &t, &id); + + if (result) { + pr_debug("%s:%d read_dev_intr failed\n", +@@ -669,7 +485,7 @@ int ps3_repository_find_interrupt(const + return result; + } + +-int ps3_repository_find_reg(const struct ps3_repository_device *dev, ++int ps3_repository_find_reg(const struct ps3_repository_device *repo, + enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) + { + int result = 0; +@@ -684,8 +500,8 @@ int ps3_repository_find_reg(const struct + u64 a; + u64 l; + +- result = ps3_repository_read_dev_reg(dev->bus_index, +- dev->dev_index, res_index, &t, &a, &l); ++ result = ps3_repository_read_dev_reg(repo->bus_index, ++ repo->dev_index, res_index, &t, &a, &l); + + if (result) { + pr_debug("%s:%d read_dev_reg failed\n", +@@ -965,6 +781,36 @@ int ps3_repository_read_boot_dat_size(un + return result; + } + ++int ps3_repository_read_vuart_av_port(unsigned int *port) ++{ ++ int result; ++ u64 v1; ++ ++ result = read_node(PS3_LPAR_ID_CURRENT, ++ make_first_field("bi", 0), ++ make_field("vir_uart", 0), ++ make_field("port", 0), ++ make_field("avset", 0), ++ &v1, 0); ++ *port = v1; ++ return result; ++} ++ ++int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) ++{ ++ int result; ++ u64 v1; ++ ++ result = read_node(PS3_LPAR_ID_CURRENT, ++ make_first_field("bi", 0), ++ make_field("vir_uart", 0), ++ make_field("port", 0), ++ make_field("sysmgr", 0), ++ &v1, 0); ++ *port = v1; ++ return result; ++} ++ + /** + * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. + * address: lpar address of cell_ext_os_area +@@ -1026,3 +872,205 @@ int ps3_repository_read_be_tb_freq(unsig + return result ? result + : ps3_repository_read_tb_freq(node_id, tb_freq); + } ++ ++#if defined(DEBUG) ++ ++int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) ++{ ++ int result = 0; ++ unsigned int res_index; ++ ++ pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ ++ for (res_index = 0; res_index < 10; res_index++) { ++ enum ps3_interrupt_type intr_type; ++ unsigned int interrupt_id; ++ ++ result = ps3_repository_read_dev_intr(repo->bus_index, ++ repo->dev_index, res_index, &intr_type, &interrupt_id); ++ ++ if (result) { ++ if (result != LV1_NO_ENTRY) ++ pr_debug("%s:%d ps3_repository_read_dev_intr" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ break; ++ } ++ ++ pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", ++ __func__, __LINE__, repo->bus_index, repo->dev_index, ++ intr_type, interrupt_id); ++ } ++ ++ for (res_index = 0; res_index < 10; res_index++) { ++ enum ps3_reg_type reg_type; ++ u64 bus_addr; ++ u64 len; ++ ++ result = ps3_repository_read_dev_reg(repo->bus_index, ++ repo->dev_index, res_index, ®_type, &bus_addr, &len); ++ ++ if (result) { ++ if (result != LV1_NO_ENTRY) ++ pr_debug("%s:%d ps3_repository_read_dev_reg" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ break; ++ } ++ ++ pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", ++ __func__, __LINE__, repo->bus_index, repo->dev_index, ++ reg_type, bus_addr, len); ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int dump_stor_dev_info(struct ps3_repository_device *repo) ++{ ++ int result = 0; ++ unsigned int num_regions, region_index; ++ u64 port, blk_size, num_blocks; ++ ++ pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ ++ result = ps3_repository_read_stor_dev_info(repo->bus_index, ++ repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); ++ if (result) { ++ pr_debug("%s:%d ps3_repository_read_stor_dev_info" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ goto out; ++ } ++ ++ pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " ++ "%lu, num_regions %u\n", ++ __func__, __LINE__, repo->bus_index, repo->dev_index, port, ++ blk_size, num_blocks, num_regions); ++ ++ for (region_index = 0; region_index < num_regions; region_index++) { ++ unsigned int region_id; ++ u64 region_start, region_size; ++ ++ result = ps3_repository_read_stor_dev_region(repo->bus_index, ++ repo->dev_index, region_index, ®ion_id, ++ ®ion_start, ®ion_size); ++ if (result) { ++ pr_debug("%s:%d ps3_repository_read_stor_dev_region" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ break; ++ } ++ ++ pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", ++ __func__, __LINE__, repo->bus_index, repo->dev_index, ++ region_id, region_start, region_size); ++ } ++ ++out: ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++static int dump_device_info(struct ps3_repository_device *repo, ++ unsigned int num_dev) ++{ ++ int result = 0; ++ ++ pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); ++ ++ for (repo->dev_index = 0; repo->dev_index < num_dev; ++ repo->dev_index++) { ++ ++ result = ps3_repository_read_dev_type(repo->bus_index, ++ repo->dev_index, &repo->dev_type); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_repository_read_dev_type" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ break; ++ } ++ ++ result = ps3_repository_read_dev_id(repo->bus_index, ++ repo->dev_index, &repo->dev_id); ++ ++ if (result) { ++ pr_debug("%s:%d ps3_repository_read_dev_id" ++ " (%u:%u) failed\n", __func__, __LINE__, ++ repo->bus_index, repo->dev_index); ++ continue; ++ } ++ ++ pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, ++ __LINE__, repo->bus_index, repo->dev_index, ++ repo->dev_type, repo->dev_id); ++ ++ ps3_repository_dump_resource_info(repo); ++ ++ if (repo->bus_type == PS3_BUS_TYPE_STORAGE) ++ dump_stor_dev_info(repo); ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++int ps3_repository_dump_bus_info(void) ++{ ++ int result = 0; ++ struct ps3_repository_device repo; ++ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ memset(&repo, 0, sizeof(repo)); ++ ++ for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { ++ unsigned int num_dev; ++ ++ result = ps3_repository_read_bus_type(repo.bus_index, ++ &repo.bus_type); ++ ++ if (result) { ++ pr_debug("%s:%d read_bus_type(%u) failed\n", ++ __func__, __LINE__, repo.bus_index); ++ break; ++ } ++ ++ result = ps3_repository_read_bus_id(repo.bus_index, ++ &repo.bus_id); ++ ++ if (result) { ++ pr_debug("%s:%d read_bus_id(%u) failed\n", ++ __func__, __LINE__, repo.bus_index); ++ continue; ++ } ++ ++ if (repo.bus_index != repo.bus_id) ++ pr_debug("%s:%d bus_index != bus_id\n", ++ __func__, __LINE__); ++ ++ result = ps3_repository_read_bus_num_dev(repo.bus_index, ++ &num_dev); ++ ++ if (result) { ++ pr_debug("%s:%d read_bus_num_dev(%u) failed\n", ++ __func__, __LINE__, repo.bus_index); ++ continue; ++ } ++ ++ pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", ++ __func__, __LINE__, repo.bus_index, repo.bus_type, ++ repo.bus_id, num_dev); ++ ++ dump_device_info(&repo, num_dev); ++ } ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return result; ++} ++ ++#endif /* defined(DEBUG) */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/44-ps3stor_disk.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/44-ps3stor_disk.patch @@ -0,0 +1,447 @@ +Subject: ps3: Disk Storage Driver + +From: Geert Uytterhoeven + +Add a Disk Storage Driver for the PS3: + - Implemented as a block device driver with a dynamic major + - Disk names (and partitions) are of the format ps3d%c(%u) + - Uses software scatter-gather with a 64 KiB bounce buffer as the hypervisor + doesn't support scatter-gather + +Signed-off-by: Geert Uytterhoeven +--- + arch/powerpc/platforms/ps3/Kconfig | 11 + + drivers/block/Makefile | 1 + drivers/block/ps3disk.c | 402 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 414 insertions(+) + +--- a/arch/powerpc/platforms/ps3/Kconfig ++++ b/arch/powerpc/platforms/ps3/Kconfig +@@ -101,4 +101,15 @@ config PS3_STORAGE + depends on PPC_PS3 + tristate + ++config PS3_DISK ++ tristate "PS3 Disk Storage Driver" ++ depends on PPC_PS3 && BLOCK ++ select PS3_STORAGE ++ default y ++ help ++ Include support for the PS3 Disk Storage. ++ ++ This support is required to access the PS3 hard disk. ++ In general, all users will say Y or M. ++ + endmenu +--- a/drivers/block/Makefile ++++ b/drivers/block/Makefile +@@ -29,3 +29,4 @@ obj-$(CONFIG_VIODASD) += viodasd.o + obj-$(CONFIG_BLK_DEV_SX8) += sx8.o + obj-$(CONFIG_BLK_DEV_UB) += ub.o + ++obj-$(CONFIG_PS3_DISK) += ps3disk.o +--- /dev/null ++++ b/drivers/block/ps3disk.c +@@ -0,0 +1,402 @@ ++/* ++ * PS3 Disk Storage Driver ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++ ++#define DEVICE_NAME "ps3disk" ++ ++#define BOUNCE_SIZE (64*1024) ++ ++// FIXME Use a fixed major assigned by LANANA? ++#define PS3DISK_MAJOR 0 ++ ++#define PS3DISK_MAX_DISKS 16 ++#define PS3DISK_MINORS 16 ++ ++#define KERNEL_SECTOR_SIZE 512 ++ ++ ++#define PS3DISK_NAME "ps3d%c" ++ ++#define LV1_STORAGE_ATA_HDDOUT (0x23) ++ ++ ++struct ps3disk_private { ++ spinlock_t lock; ++ struct task_struct *thread; ++ struct request_queue *queue; ++ struct gendisk *gendisk; ++ unsigned int blocking_factor; ++}; ++#define ps3disk_priv(dev) ((dev)->sbd.core.driver_data) ++ ++static int ps3disk_major = PS3DISK_MAJOR; ++ ++static int ps3disk_open(struct inode *inode, struct file *file) ++{ ++ struct ps3_storage_device *dev = inode->i_bdev->bd_disk->private_data; ++ ++ file->private_data = dev; ++ return 0; ++} ++ ++ ++ ++static struct block_device_operations ps3disk_fops = { ++ .owner = THIS_MODULE, ++ .open = ps3disk_open, ++}; ++ ++static void ps3disk_scatter_gather(struct ps3_storage_device *dev, ++ struct request *req, int gather) ++{ ++ unsigned int sectors = 0, offset = 0; ++ struct bio *bio; ++ sector_t sector; ++ struct bio_vec *bvec; ++ unsigned int i = 0, j; ++ size_t size; ++ void *buf; ++ ++ rq_for_each_bio(bio, req) { ++ sector = bio->bi_sector; ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: bio %u: %u segs %u sectors from %lu\n", ++ __func__, __LINE__, i, bio_segments(bio), ++ bio_sectors(bio), sector); ++ bio_for_each_segment(bvec, bio, j) { ++ size = bio_cur_sectors(bio)*KERNEL_SECTOR_SIZE; ++ buf = __bio_kmap_atomic(bio, j, KM_USER0); ++ if (gather) ++ memcpy(dev->bounce_buf+offset, buf, size); ++ else ++ memcpy(buf, dev->bounce_buf+offset, size); ++ offset += size; ++ __bio_kunmap_atomic(bio, KM_USER0); ++ } ++ sectors += bio_sectors(bio); ++ i++; ++ } ++} ++ ++static void ps3disk_handle_request_sg(struct ps3_storage_device *dev, ++ struct request *req) ++{ ++ struct ps3disk_private *priv = ps3disk_priv(dev); ++ int uptodate = 1; ++ int write = rq_data_dir(req); ++ const char *op = write ? "write" : "read"; ++ u64 res; ++ ++#ifdef DEBUG ++ unsigned int n = 0; ++ struct bio *bio; ++ rq_for_each_bio(bio, req) ++ n++; ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: %s req has %u bios for %lu sectors %lu hard sectors\n", ++ __func__, __LINE__, op, n, req->nr_sectors, ++ req->hard_nr_sectors); ++#endif ++ ++ if (write) ++ ps3disk_scatter_gather(dev, req, 1); ++ ++ res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, ++ req->sector*priv->blocking_factor, ++ req->nr_sectors*priv->blocking_factor, ++ write); ++ if (res) { ++ dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, ++ __LINE__, op, res); ++ uptodate = 0; ++ } else if (!write) ++ ps3disk_scatter_gather(dev, req, 0); ++ ++ spin_lock_irq(&priv->lock); ++ if (!end_that_request_first(req, uptodate, req->nr_sectors)) { ++ blkdev_dequeue_request(req); ++ end_that_request_last(req, uptodate); ++ } ++ spin_unlock_irq(&priv->lock); ++} ++ ++static int ps3disk_thread(void *data) ++{ ++ struct ps3_storage_device *dev = data; ++ struct ps3disk_private *priv = ps3disk_priv(dev); ++ request_queue_t *q = priv->queue; ++ struct request *req; ++ ++ dev_dbg(&dev->sbd.core, "%s thread init\n", __func__); ++ ++ current->flags |= PF_NOFREEZE; ++ ++ while (!kthread_should_stop()) { ++ spin_lock_irq(&priv->lock); ++ set_current_state(TASK_INTERRUPTIBLE); ++ req = elv_next_request(q); ++ if (!req) { ++ spin_unlock_irq(&priv->lock); ++ schedule(); ++ continue; ++ } ++ if (!blk_fs_request(req)) { ++ blk_dump_rq_flags(req, DEVICE_NAME " bad request"); ++ end_request(req, 0); ++ spin_unlock_irq(&priv->lock); ++ continue; ++ } ++ spin_unlock_irq(&priv->lock); ++ ps3disk_handle_request_sg(dev, req); ++ } ++ ++ dev_dbg(&dev->sbd.core, "%s thread exit\n", __func__); ++ return 0; ++} ++ ++static int ps3disk_sync_cache(struct ps3_storage_device *dev) ++{ ++ int res; ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: sync cache\n", __func__, __LINE__); ++ ++ res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0); ++ if (res) { ++ dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n", ++ __func__, __LINE__, dev->lv1_status); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ps3disk_issue_flush(request_queue_t *q, struct gendisk *gendisk, ++ sector_t *sector) ++{ ++ struct ps3_storage_device *dev = q->queuedata; ++ return ps3disk_sync_cache(dev); ++} ++ ++static void ps3disk_prepare_flush(request_queue_t *q, struct request *req) ++{ ++ // FIXME Is this the correct thing to do? ++ struct ps3_storage_device *dev = q->queuedata; ++ ps3disk_sync_cache(dev); ++ memset(req->cmd, 0, sizeof(req->cmd)); ++ req->cmd_type = REQ_TYPE_FLUSH; ++} ++ ++static void ps3disk_request(request_queue_t *q) ++{ ++ struct ps3_storage_device *dev = q->queuedata; ++ struct ps3disk_private *priv = ps3disk_priv(dev); ++ wake_up_process(priv->thread); ++} ++ ++static unsigned long ps3disk_mask; ++ ++static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ struct ps3disk_private *priv; ++ int error; ++ unsigned int devidx; ++ struct request_queue *queue; ++ struct gendisk *gendisk; ++ struct task_struct *task; ++ ++ if (dev->blk_size < KERNEL_SECTOR_SIZE) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: cannot handle block size %lu\n", __func__, ++ __LINE__, dev->blk_size); ++ return -EINVAL; ++ } ++ ++ BUILD_BUG_ON(PS3DISK_MAX_DISKS > BITS_PER_LONG); ++ devidx = find_first_zero_bit(&ps3disk_mask, PS3DISK_MAX_DISKS); ++ if (devidx >= PS3DISK_MAX_DISKS) { ++ dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__, ++ __LINE__); ++ return -ENOSPC; ++ } ++ __set_bit(devidx, &ps3disk_mask); ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) { ++ error = -ENOMEM; ++ goto fail; ++ } ++ ++ ps3disk_priv(dev) = priv; ++ spin_lock_init(&priv->lock); ++ ++ dev->bounce_size = BOUNCE_SIZE; ++ dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA); ++ if (!dev->bounce_buf) { ++ error = -ENOMEM; ++ goto fail_free_priv; ++ } ++ ++ error = ps3stor_setup(dev, DEVICE_NAME); ++ if (error) ++ goto fail_free_bounce; ++ ++ queue = blk_init_queue(ps3disk_request, &priv->lock); ++ if (!queue) { ++ dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n", ++ __func__, __LINE__); ++ error = -ENOMEM; ++ goto fail_teardown; ++ } ++ ++ priv->queue = queue; ++ queue->queuedata = dev; ++ ++ blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH); ++ ++ blk_queue_max_sectors(queue, dev->bounce_size/KERNEL_SECTOR_SIZE); ++ blk_queue_segment_boundary(queue, -1UL); ++ blk_queue_dma_alignment(queue, dev->blk_size-1); ++ blk_queue_hardsect_size(queue, dev->blk_size); ++ ++ blk_queue_issue_flush_fn(queue, ps3disk_issue_flush); ++ blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH, ++ ps3disk_prepare_flush); ++ ++ blk_queue_max_phys_segments(queue, -1); ++ blk_queue_max_hw_segments(queue, -1); ++ blk_queue_max_segment_size(queue, dev->bounce_size); ++ ++ gendisk = alloc_disk(PS3DISK_MINORS); ++ if (!gendisk) { ++ dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__, ++ __LINE__); ++ error = -ENOMEM; ++ goto fail_cleanup_queue; ++ } ++ ++ priv->gendisk = gendisk; ++ gendisk->major = ps3disk_major; ++ gendisk->first_minor = devidx * PS3DISK_MINORS; ++ gendisk->fops = &ps3disk_fops; ++ gendisk->queue = queue; ++ gendisk->private_data = dev; ++ snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME, ++ devidx+'a'); ++ priv->blocking_factor = dev->blk_size/KERNEL_SECTOR_SIZE; ++ set_capacity(gendisk, ++ dev->regions[dev->region_idx].size*priv->blocking_factor); ++ ++ task = kthread_run(ps3disk_thread, dev, DEVICE_NAME); ++ if (IS_ERR(task)) { ++ error = PTR_ERR(task); ++ goto fail_free_disk; ++ } ++ priv->thread = task; ++ ++ add_disk(gendisk); ++ return 0; ++ ++fail_free_disk: ++ put_disk(priv->gendisk); ++fail_cleanup_queue: ++ blk_cleanup_queue(queue); ++fail_teardown: ++ ps3stor_teardown(dev); ++fail_free_bounce: ++ kfree(dev->bounce_buf); ++fail_free_priv: ++ kfree(priv); ++fail: ++ __clear_bit(devidx, &ps3disk_mask); ++ return error; ++} ++ ++static int ps3disk_remove(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ struct ps3disk_private *priv = ps3disk_priv(dev); ++ ++ kthread_stop(priv->thread); ++ __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS, ++ &ps3disk_mask); ++ del_gendisk(priv->gendisk); ++ put_disk(priv->gendisk); ++ blk_cleanup_queue(priv->queue); ++ dev_notice(&dev->sbd.core, "Synchronizing disk cache\n"); ++ ps3disk_sync_cache(dev); ++ ps3stor_teardown(dev); ++ kfree(dev->bounce_buf); ++ kfree(priv); ++ return 0; ++} ++ ++ ++static struct ps3_system_bus_driver ps3disk = { ++ .match_id = PS3_MATCH_ID_STOR_DISK, ++ .core.name = DEVICE_NAME, ++ .core.owner = THIS_MODULE, ++ .probe = ps3disk_probe, ++ .remove = ps3disk_remove, ++ .shutdown = ps3disk_remove, ++}; ++ ++ ++static int __init ps3disk_init(void) ++{ ++ int error; ++ ++ error = register_blkdev(ps3disk_major, DEVICE_NAME); ++ if (error <= 0) { ++ printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__, ++ __LINE__, error); ++ return error; ++ } ++ if (!ps3disk_major) ++ ps3disk_major = error; ++ ++ pr_info("%s:%u: registered block device major %d\n", __func__, ++ __LINE__, ps3disk_major); ++ ++ return ps3_system_bus_driver_register(&ps3disk); ++} ++ ++static void __exit ps3disk_exit(void) ++{ ++ unregister_blkdev(ps3disk_major, DEVICE_NAME); ++ ++ ps3_system_bus_driver_unregister(&ps3disk); ++} ++ ++module_init(ps3disk_init); ++module_exit(ps3disk_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("PS3 Disk Storage Driver"); ++MODULE_AUTHOR("Sony Corporation"); ++MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_DISK); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/48-spufs-clear-class-0-interrupt.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/48-spufs-clear-class-0-interrupt.patch @@ -0,0 +1,92 @@ +From: Masato Noguchi + +In the PS3 platform, all interrupts are virtuailzed by hypervisor. +Thus, there is a little difference between baremetal and PS3. + +Cell BE Architecture says SPU MFC class 0 interrupt is a pulse. +That means, once interrupt raised, never re-raised until someone +changes interrupt status. + +Current spufs inplementation rely on it. +Class 0 handler just wake up a process and interrupt status is +cleared by that process at outside of interrupt handler. + +While, the PS3 hypervisor treats all SPU interrupt as a level. +That means, if unmasked interrupt status bit remaind at +the end of interrupt handler, the hypervisor creates renewed +virtual interrupt packet. + +Thus, Current kernel will freeze by interrupts raised +over and over again, once SPE raised class 0 interrupt. + + +Signed-off-by: Masato Noguchi +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/cell/spu_base.c | 23 +++++++++++++++-------- + include/asm-powerpc/spu.h | 2 +- + 2 files changed, 16 insertions(+), 9 deletions(-) + +--- ps3-linux-2.6.20.orig/arch/powerpc/platforms/cell/spu_base.c ++++ ps3-linux-2.6.20/arch/powerpc/platforms/cell/spu_base.c +@@ -158,27 +158,34 @@ static irqreturn_t + spu_irq_class_0(int irq, void *data) + { + struct spu *spu; ++ unsigned long stat, mask; + + spu = data; +- spu->class_0_pending = 1; ++ ++ mask = spu_int_mask_get(spu, 0); ++ stat = spu_int_stat_get(spu, 0); ++ stat &= mask; ++ ++ spin_lock(&spu->register_lock); ++ spu->class_0_pending |= stat; ++ spin_unlock(&spu->register_lock); ++ + spu->stop_callback(spu); + ++ spu_int_stat_clear(spu, 0, stat); ++ + return IRQ_HANDLED; + } + + int + spu_irq_class_0_bottom(struct spu *spu) + { +- unsigned long stat, mask; + unsigned long flags; +- +- spu->class_0_pending = 0; ++ unsigned long stat; + + spin_lock_irqsave(&spu->register_lock, flags); +- mask = spu_int_mask_get(spu, 0); +- stat = spu_int_stat_get(spu, 0); +- +- stat &= mask; ++ stat = spu->class_0_pending; ++ spu->class_0_pending = 0; + + if (stat & 1) /* invalid DMA alignment */ + __spu_trap_dma_align(spu); +--- ps3-linux-2.6.20.orig/include/asm-powerpc/spu.h ++++ ps3-linux-2.6.20/include/asm-powerpc/spu.h +@@ -122,6 +122,7 @@ struct spu { + u64 flags; + u64 dar; + u64 dsisr; ++ u64 class_0_pending; + size_t ls_size; + unsigned int slb_replace; + struct mm_struct *mm; +@@ -129,7 +130,6 @@ struct spu { + struct spu_runqueue *rq; + unsigned long long timestamp; + pid_t pid; +- int class_0_pending; + spinlock_t register_lock; + + void (* wbox_callback)(struct spu *spu); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/38-logo-extern-in-header.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/38-logo-extern-in-header.patch @@ -0,0 +1,90 @@ +Subject: [PATCH 4/8] fbdev: move logo externs to header file + +Move the external declarations for the various linux logo structures to +. As a consequence, I had to change scripts/pnmtologo.c to +add the appropriate `const' to the generated logo source code. + +FIXME: This one is really tricky and cannot be applied! + - gcc 3.4.6 20060404 (Red Hat 3.4.6-3) needs xxx_data[] and + xxx_clut[] to be const too, else it complains about a section type conflict + - ppu-gcc 4.1.0 20060304 (Red Hat 4.1.0-3) needs xxx_data[] and xxx_clut[] to + be non-const, else it complains about a section type conflict +Anyone with a suggestion how to fix this? + +Signed-off-by: Geert Uytterhoeven +Acked-By: James Simmons +--- + arch/powerpc/kernel/prom_init.c | 3 --- + drivers/video/logo/logo.c | 13 ------------- + include/linux/linux_logo.h | 13 +++++++++++++ + scripts/pnmtologo.c | 2 +- + 4 files changed, 14 insertions(+), 17 deletions(-) + +--- ps3-linux-2.6.21.orig/arch/powerpc/kernel/prom_init.c ++++ ps3-linux-2.6.21/arch/powerpc/kernel/prom_init.c +@@ -44,10 +44,7 @@ + #include + #include + +-#ifdef CONFIG_LOGO_LINUX_CLUT224 + #include +-extern const struct linux_logo logo_linux_clut224; +-#endif + + /* + * Properties whose value is longer than this get excluded from our +--- ps3-linux-2.6.21.orig/drivers/video/logo/logo.c ++++ ps3-linux-2.6.21/drivers/video/logo/logo.c +@@ -21,19 +21,6 @@ + #include + #endif + +-extern const struct linux_logo logo_linux_mono; +-extern const struct linux_logo logo_linux_vga16; +-extern const struct linux_logo logo_linux_clut224; +-extern const struct linux_logo logo_dec_clut224; +-extern const struct linux_logo logo_mac_clut224; +-extern const struct linux_logo logo_parisc_clut224; +-extern const struct linux_logo logo_sgi_clut224; +-extern const struct linux_logo logo_sun_clut224; +-extern const struct linux_logo logo_superh_mono; +-extern const struct linux_logo logo_superh_vga16; +-extern const struct linux_logo logo_superh_clut224; +-extern const struct linux_logo logo_m32r_clut224; +- + + const struct linux_logo *fb_find_logo(int depth) + { +--- ps3-linux-2.6.21.orig/include/linux/linux_logo.h ++++ ps3-linux-2.6.21/include/linux/linux_logo.h +@@ -32,6 +32,19 @@ struct linux_logo { + const unsigned char *data; + }; + ++extern const struct linux_logo logo_linux_mono; ++extern const struct linux_logo logo_linux_vga16; ++extern const struct linux_logo logo_linux_clut224; ++extern const struct linux_logo logo_dec_clut224; ++extern const struct linux_logo logo_mac_clut224; ++extern const struct linux_logo logo_parisc_clut224; ++extern const struct linux_logo logo_sgi_clut224; ++extern const struct linux_logo logo_sun_clut224; ++extern const struct linux_logo logo_superh_mono; ++extern const struct linux_logo logo_superh_vga16; ++extern const struct linux_logo logo_superh_clut224; ++extern const struct linux_logo logo_m32r_clut224; ++ + extern const struct linux_logo *fb_find_logo(int depth); + + #endif /* _LINUX_LINUX_LOGO_H */ +--- ps3-linux-2.6.21.orig/scripts/pnmtologo.c ++++ ps3-linux-2.6.21/scripts/pnmtologo.c +@@ -244,7 +244,7 @@ static void write_header(void) + static void write_footer(void) + { + fputs("\n};\n\n", out); +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname); ++ fprintf(out, "const struct linux_logo %s __initdata = {\n", logoname); + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]); + fprintf(out, " .width\t= %d,\n", logo_width); + fprintf(out, " .height\t= %d,\n", logo_height); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/32-ps3-dts.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/32-ps3-dts.patch @@ -0,0 +1,86 @@ +Subject: PS3: Device tree source. + +The PS3 device tree source. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/boot/dts/ps3.dts | 74 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +--- /dev/null ++++ b/arch/powerpc/boot/dts/ps3.dts +@@ -0,0 +1,74 @@ ++/* ++ * PS3 Game Console device tree. ++ * ++ * Copyright (C) 2006 Sony Computer Entertainment Inc. ++ * Copyright 2006 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++ ++/ { ++ model = "PS3 Game Console"; ++ compatible = "PS3"; ++ #size-cells = <2>; ++ #address-cells = <2>; ++ ++ /* ++ * Need to keep linux,platform for a while, not used by kernel. ++ */ ++ ++ chosen { ++ linux,platform = <0>; ++ }; ++ ++ /* ++ * dtc expects a memory entry, so we'll put a null entry here. ++ * We'll get the size of the bootmem block from lv1 after startup. ++ */ ++ ++ memory { ++ device_type = "memory"; ++ reg = <0 0 0 0>; ++ }; ++ ++ /* ++ * dtc expects a clock-frequency and timebase-frequency entries, so ++ * we'll put a null entries here. These will be initialized after ++ * startup with data from lv1. ++ * ++ * The boot cpu is always zero for PS3. ++ * ++ * Seems the only way currently to indicate a processor has multiple ++ * threads is with an ibm,ppc-interrupt-server#s entry. We'll put one ++ * here so we can bring up both of ours. See smp_setup_cpu_maps(). ++ */ ++ ++ cpus { ++ #size-cells = <0>; ++ #address-cells = <1>; ++ ++ CBE,PPE { ++ device_type = "cpu"; ++ reg = <0>; ++ ibm,ppc-interrupt-server#s = <0 1>; ++ clock-frequency = <0>; ++ timebase-frequency = <0>; ++ i-cache-size = <8000>; ++ d-cache-size = <8000>; ++ i-cache-line-size = <80>; ++ d-cache-line-size = <80>; ++ }; ++ }; ++}; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/20-ps3-system-bus-rework-ps3fb.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/20-ps3-system-bus-rework-ps3fb.patch @@ -0,0 +1,535 @@ +Subject: PS3: Frame buffer system-bus rework +CC: linux-fbdev-devel@lists.sourceforge.net + +Convert the ps3fb device from a platform device to a PS3 system bus device. +Fix the remove and shutdown methods to support kexec and to make ps3fb a +loadable module. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/setup.c | 9 - + drivers/video/Kconfig | 4 + drivers/video/ps3fb.c | 288 ++++++++++++++++--------------------- + include/asm-powerpc/ps3fb.h | 12 - + 4 files changed, 132 insertions(+), 181 deletions(-) + +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -107,7 +107,7 @@ static void ps3_panic(char *str) + while(1); + } + +-#ifdef CONFIG_FB_PS3 ++#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) + static void prealloc(struct ps3_prealloc *p) + { + if (!p->size) +@@ -125,10 +125,11 @@ static void prealloc(struct ps3_prealloc + } + + struct ps3_prealloc ps3fb_videomemory = { +- .name = "ps3fb videomemory", +- .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, +- .align = 1024*1024 /* the GPU requires 1 MiB alignment */ ++ .name = "ps3fb videomemory", ++ .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, ++ .align = 1024*1024 /* the GPU requires 1 MiB alignment */ + }; ++EXPORT_SYMBOL_GPL(ps3fb_videomemory); + #define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory) + + static int __init early_parse_ps3fb(char *p) +--- a/drivers/video/Kconfig ++++ b/drivers/video/Kconfig +@@ -1790,8 +1790,8 @@ config FB_IBM_GXT4500 + adaptor, found on some IBM System P (pSeries) machines. + + config FB_PS3 +- bool "PS3 GPU framebuffer driver" +- depends on (FB = y) && PS3_PS3AV ++ tristate "PS3 GPU framebuffer driver" ++ depends on FB && PS3_PS3AV + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT +--- a/drivers/video/ps3fb.c ++++ b/drivers/video/ps3fb.c +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -46,6 +45,9 @@ + #include + #include + ++ ++#define DEVICE_NAME "ps3fb" ++ + #ifdef PS3FB_DEBUG + #define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args) + #else +@@ -126,7 +128,6 @@ struct gpu_driver_info { + + struct ps3fb_priv { + unsigned int irq_no; +- void *dev; + + u64 context_handle, memory_handle; + void *xdr_ea; +@@ -171,7 +172,7 @@ static const struct ps3fb_res_table ps3f + { 0, 0, 0, 0 , 0} }; + + /* default resolution */ +-#define GPU_RES_INDEX 0 /* 720 x 480 */ ++#define GPU_RES_INDEX 0 /* 720 x 480 */ + + static const struct fb_videomode ps3fb_modedb[] = { + /* 60 Hz broadcast modes (modes "1" to "5") */ +@@ -298,10 +299,9 @@ static const struct fb_videomode ps3fb_m + #define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET) + + static int ps3fb_mode; +-module_param(ps3fb_mode, bool, 0); +- +-static char *mode_option __initdata; ++module_param(ps3fb_mode, int, 0); + ++static char *mode_option __devinitdata; + + static int ps3fb_get_res_table(u32 xres, u32 yres) + { +@@ -681,15 +681,15 @@ int ps3fb_wait_for_vsync(u32 crtc) + + EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync); + +-void ps3fb_flip_ctl(int on) ++void ps3fb_flip_ctl(int on, void *data) + { ++ struct ps3fb_priv *priv = data; + if (on) +- atomic_dec_if_positive(&ps3fb.ext_flip); ++ atomic_dec_if_positive(&priv->ext_flip); + else +- atomic_inc(&ps3fb.ext_flip); ++ atomic_inc(&priv->ext_flip); + } + +-EXPORT_SYMBOL_GPL(ps3fb_flip_ctl); + + /* + * ioctl +@@ -851,37 +851,9 @@ static irqreturn_t ps3fb_vsync_interrupt + return IRQ_HANDLED; + } + +-#ifndef MODULE +-static int __init ps3fb_setup(char *options) +-{ +- char *this_opt; +- int mode = 0; + +- if (!options || !*options) +- return 0; /* no options */ +- +- while ((this_opt = strsep(&options, ",")) != NULL) { +- if (!*this_opt) +- continue; +- if (!strncmp(this_opt, "mode:", 5)) +- mode = simple_strtoul(this_opt + 5, NULL, 0); +- else +- mode_option = this_opt; +- } +- return mode; +-} +-#endif /* MODULE */ +- +- /* +- * Initialisation +- */ +- +-static void ps3fb_platform_release(struct device *device) +-{ +- /* This is called when the reference count goes to zero. */ +-} +- +-static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) ++static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, ++ struct ps3_system_bus_device *dev) + { + int error; + +@@ -897,7 +869,6 @@ static int ps3fb_vsync_settings(struct g + return -EINVAL; + } + +- ps3fb.dev = dev; + error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, + &ps3fb.irq_no); + if (error) { +@@ -907,7 +878,7 @@ static int ps3fb_vsync_settings(struct g + } + + error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, +- "ps3fb vsync", ps3fb.dev); ++ DEVICE_NAME, dev); + if (error) { + printk(KERN_ERR "%s: request_irq failed %d\n", __func__, + error); +@@ -966,16 +937,47 @@ static struct fb_ops ps3fb_ops = { + }; + + static struct fb_fix_screeninfo ps3fb_fix __initdata = { +- .id = "PS3 FB", ++ .id = DEVICE_NAME, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .accel = FB_ACCEL_NONE, + }; + +-static int __init ps3fb_probe(struct platform_device *dev) ++static int ps3fb_set_sync(void) ++{ ++ int status; ++ ++#ifdef HEAD_A ++ status = lv1_gpu_context_attribute(0x0, ++ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, ++ 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); ++ if (status) { ++ printk(KERN_ERR ++ "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n", ++ __func__, status); ++ return -1; ++ } ++#endif ++#ifdef HEAD_B ++ status = lv1_gpu_context_attribute(0x0, ++ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, ++ 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); ++ ++ if (status) { ++ printk(KERN_ERR ++ "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n", ++ __func__, status); ++ return -1; ++ } ++#endif ++ return 0; ++} ++ ++static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) + { + struct fb_info *info; + int retval = -ENOMEM; ++ u32 xres, yres; + u64 ddr_lpar = 0; + u64 lpar_dma_control = 0; + u64 lpar_driver_info = 0; +@@ -986,6 +988,30 @@ static int __init ps3fb_probe(struct pla + unsigned long offset; + struct task_struct *task; + ++ status = ps3_open_hv_device(dev); ++ if (status) { ++ printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__); ++ goto err; ++ } ++ ++ if (!ps3fb_mode) ++ ps3fb_mode = ps3av_get_mode(); ++ DPRINTK("ps3av_mode:%d\n", ps3fb_mode); ++ ++ if (ps3fb_mode > 0 && ++ !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) { ++ ps3fb.res_index = ps3fb_get_res_table(xres, yres); ++ DPRINTK("res_index:%d\n", ps3fb.res_index); ++ } else ++ ps3fb.res_index = GPU_RES_INDEX; ++ ++ atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ ++ atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ ++ init_waitqueue_head(&ps3fb.wait_vsync); ++ ps3fb.num_frames = 1; ++ ++ ps3fb_set_sync(); ++ + /* get gpu context handle */ + status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0, + &ps3fb.memory_handle, &ddr_lpar); +@@ -1029,7 +1055,7 @@ static int __init ps3fb_probe(struct pla + * leakage into userspace + */ + memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); +- info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); ++ info = framebuffer_alloc(sizeof(u32) * 16, &dev->core); + if (!info) + goto err_free_irq; + +@@ -1061,19 +1087,20 @@ static int __init ps3fb_probe(struct pla + if (retval < 0) + goto err_fb_dealloc; + +- platform_set_drvdata(dev, info); ++ dev->core.driver_data = info; + + printk(KERN_INFO + "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n", + info->node, ps3fb_videomemory.size >> 10); + +- task = kthread_run(ps3fbd, info, "ps3fbd"); ++ task = kthread_run(ps3fbd, info, DEVICE_NAME); + if (IS_ERR(task)) { + retval = PTR_ERR(task); + goto err_unregister_framebuffer; + } + + ps3fb.task = task; ++ ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb); + + return 0; + +@@ -1084,7 +1111,7 @@ err_fb_dealloc: + err_framebuffer_release: + framebuffer_release(info); + err_free_irq: +- free_irq(ps3fb.irq_no, ps3fb.dev); ++ free_irq(ps3fb.irq_no, dev); + ps3_irq_plug_destroy(ps3fb.irq_no); + err_iounmap_dinfo: + iounmap((u8 __iomem *)ps3fb.dinfo); +@@ -1096,26 +1123,30 @@ err: + return retval; + } + +-static void ps3fb_shutdown(struct platform_device *dev) ++static int ps3fb_shutdown(struct ps3_system_bus_device *dev) + { +- ps3fb_flip_ctl(0); /* flip off */ ++ int status; ++ struct fb_info *info = dev->core.driver_data; ++ ++ DPRINTK(" -> %s:%d\n", __func__, __LINE__); ++ ++ ps3fb_flip_ctl(0, &ps3fb); /* flip off */ + ps3fb.dinfo->irq.mask = 0; +- free_irq(ps3fb.irq_no, ps3fb.dev); +- ps3_irq_plug_destroy(ps3fb.irq_no); +- iounmap((u8 __iomem *)ps3fb.dinfo); +-} + +-void ps3fb_cleanup(void) +-{ +- int status; ++ if (info) { ++ unregister_framebuffer(info); ++ fb_dealloc_cmap(&info->cmap); ++ framebuffer_release(info); ++ } + ++ ps3av_register_flip_ctl(NULL, NULL); + if (ps3fb.task) { + struct task_struct *task = ps3fb.task; + ps3fb.task = NULL; + kthread_stop(task); + } + if (ps3fb.irq_no) { +- free_irq(ps3fb.irq_no, ps3fb.dev); ++ free_irq(ps3fb.irq_no, dev); + ps3_irq_plug_destroy(ps3fb.irq_no); + } + iounmap((u8 __iomem *)ps3fb.dinfo); +@@ -1128,134 +1159,65 @@ void ps3fb_cleanup(void) + if (status) + DPRINTK("lv1_gpu_memory_free failed: %d\n", status); + +- ps3av_dev_close(); +-} +- +-EXPORT_SYMBOL_GPL(ps3fb_cleanup); +- +-static int ps3fb_remove(struct platform_device *dev) +-{ +- struct fb_info *info = platform_get_drvdata(dev); ++ ps3_close_hv_device(dev); ++ DPRINTK(" <- %s:%d\n", __func__, __LINE__); + +- if (info) { +- unregister_framebuffer(info); +- fb_dealloc_cmap(&info->cmap); +- framebuffer_release(info); +- } +- ps3fb_cleanup(); + return 0; + } + +-static struct platform_driver ps3fb_driver = { +- .probe = ps3fb_probe, +- .remove = ps3fb_remove, +- .shutdown = ps3fb_shutdown, +- .driver = { .name = "ps3fb" } ++static struct ps3_system_bus_driver ps3fb_driver = { ++ .match_id = PS3_MATCH_ID_GRAPHICS, ++ .core.name = DEVICE_NAME, ++ .core.owner = THIS_MODULE, ++ .probe = ps3fb_probe, ++ .remove = ps3fb_shutdown, ++ .shutdown = ps3fb_shutdown, + }; + +-static struct platform_device ps3fb_device = { +- .name = "ps3fb", +- .id = 0, +- .dev = { .release = ps3fb_platform_release } +-}; +- +-int ps3fb_set_sync(void) ++static int __init ps3fb_setup(void) + { +- int status; ++ char *options, *this_opt; + +-#ifdef HEAD_A +- status = lv1_gpu_context_attribute(0x0, +- L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, +- 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); +- if (status) { +- printk(KERN_ERR +- "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n", +- __func__, status); +- return -1; +- } ++#ifdef MODULE ++ return 0; + #endif +-#ifdef HEAD_B +- status = lv1_gpu_context_attribute(0x0, +- L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, +- 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); + +- if (status) { +- printk(KERN_ERR +- "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n", +- __func__, status); +- return -1; ++ if (fb_get_options(DEVICE_NAME, &options)) ++ return -ENXIO; ++ ++ if (!options || !*options) ++ return 0; ++ ++ while ((this_opt = strsep(&options, ",")) != NULL) { ++ if (!*this_opt) ++ continue; ++ if (!strncmp(this_opt, "mode:", 5)) ++ ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0); ++ else ++ mode_option = this_opt; + } +-#endif + return 0; + } + +-EXPORT_SYMBOL_GPL(ps3fb_set_sync); +- + static int __init ps3fb_init(void) + { +- int error; +-#ifndef MODULE +- int mode; +- char *option = NULL; +- +- if (fb_get_options("ps3fb", &option)) +- goto err; +-#endif +- +- if (!ps3fb_videomemory.address) +- goto err; +- +- error = ps3av_dev_open(); +- if (error) { +- printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__); +- goto err; +- } +- +- ps3fb_mode = ps3av_get_mode(); +- DPRINTK("ps3av_mode:%d\n", ps3fb_mode); +-#ifndef MODULE +- mode = ps3fb_setup(option); /* check boot option */ +- if (mode) +- ps3fb_mode = mode; +-#endif +- if (ps3fb_mode > 0) { +- u32 xres, yres; +- ps3av_video_mode2res(ps3fb_mode, &xres, &yres); +- ps3fb.res_index = ps3fb_get_res_table(xres, yres); +- DPRINTK("res_index:%d\n", ps3fb.res_index); +- } else +- ps3fb.res_index = GPU_RES_INDEX; +- +- atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ +- atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ +- init_waitqueue_head(&ps3fb.wait_vsync); +- ps3fb.num_frames = 1; +- +- error = platform_driver_register(&ps3fb_driver); +- if (!error) { +- error = platform_device_register(&ps3fb_device); +- if (error) +- platform_driver_unregister(&ps3fb_driver); +- } +- +- ps3fb_set_sync(); +- +- return error; ++ if (!ps3fb_videomemory.address || ps3fb_setup()) ++ return -ENXIO; + +-err: +- return -ENXIO; ++ return ps3_system_bus_driver_register(&ps3fb_driver); + } + +-module_init(ps3fb_init); +- +-#ifdef MODULE + static void __exit ps3fb_exit(void) + { +- platform_device_unregister(&ps3fb_device); +- platform_driver_unregister(&ps3fb_driver); ++ DPRINTK(" -> %s:%d\n", __func__, __LINE__); ++ ps3_system_bus_driver_unregister(&ps3fb_driver); ++ DPRINTK(" <- %s:%d\n", __func__, __LINE__); + } + ++module_init(ps3fb_init); + module_exit(ps3fb_exit); + + MODULE_LICENSE("GPL"); +-#endif /* MODULE */ ++MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver"); ++MODULE_AUTHOR("Sony Computer Entertainment Inc."); ++MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS); +--- a/include/asm-powerpc/ps3fb.h ++++ b/include/asm-powerpc/ps3fb.h +@@ -41,16 +41,4 @@ struct ps3fb_ioctl_res { + __u32 num_frames; /* num of frame buffers */ + }; + +-#ifdef __KERNEL__ +- +-#ifdef CONFIG_FB_PS3 +-extern void ps3fb_flip_ctl(int on); +-extern void ps3fb_cleanup(void); +-#else +-static inline void ps3fb_flip_ctl(int on) {} +-static inline void ps3fb_cleanup(void) {} +-#endif +- +-#endif /* __KERNEL__ */ +- + #endif /* _ASM_POWERPC_PS3FB_H_ */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/40-logo_spe_clut224.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/40-logo_spe_clut224.patch @@ -0,0 +1,321 @@ +Subject: [PATCH 7/8] fbdev: SPE helper penguin logo + +Add the SPE helper penguin logo + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +Cc: Arnd Bergmann +Acked-By: James Simmons +--- + drivers/video/logo/Makefile | 2 + drivers/video/logo/logo_spe_clut224.ppm | 283 ++++++++++++++++++++++++++++++++ + include/linux/linux_logo.h | 1 + 3 files changed, 286 insertions(+) + +--- ps3-linux-2.6.21.orig/drivers/video/logo/Makefile ++++ ps3-linux-2.6.21/drivers/video/logo/Makefile +@@ -14,6 +14,8 @@ obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo + obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o + obj-$(CONFIG_LOGO_M32R_CLUT224) += logo_m32r_clut224.o + ++obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o ++ + # How to generate logo's + + # Use logo-cfiles to retrieve list of .c files to be built +--- /dev/null ++++ ps3-linux-2.6.21/drivers/video/logo/logo_spe_clut224.ppm +@@ -0,0 +1,283 @@ ++P3 ++40 40 ++255 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 6 6 6 ++15 15 15 21 21 21 19 19 19 14 14 14 6 6 6 2 2 2 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 2 2 2 21 21 21 55 55 55 ++56 56 56 54 54 54 53 53 53 60 60 60 56 56 56 25 25 25 ++6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 2 2 2 27 27 27 62 62 62 17 17 19 ++2 2 6 2 2 6 2 2 6 2 2 6 16 16 18 57 57 57 ++45 45 45 8 8 8 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 16 16 16 62 62 62 8 8 10 2 2 6 ++2 2 6 2 2 6 2 2 6 12 12 14 67 67 67 16 16 17 ++45 45 45 41 41 41 4 4 4 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 2 2 2 35 35 35 40 40 40 2 2 6 2 2 6 ++2 2 6 2 2 6 2 2 6 15 15 17 70 70 70 27 27 27 ++3 3 6 62 62 62 20 20 20 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 4 4 4 58 58 58 12 12 14 2 2 6 2 2 6 ++2 2 6 2 2 6 2 2 6 4 4 7 4 4 7 2 2 6 ++2 2 6 34 34 36 40 40 40 3 3 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 7 7 7 64 64 64 2 2 6 5 5 5 17 17 17 ++3 3 6 2 2 6 2 2 6 15 15 15 21 21 21 7 7 10 ++2 2 6 8 8 10 62 62 62 6 6 6 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 7 7 7 66 66 66 5 5 8 122 122 122 122 122 122 ++9 9 11 3 3 6 104 96 81 179 179 179 122 122 122 13 13 13 ++2 2 6 2 2 6 67 67 67 10 10 10 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 7 7 7 65 65 65 41 41 43 152 149 142 192 191 189 ++48 48 49 23 23 24 228 210 210 86 86 86 192 191 189 59 59 61 ++2 2 6 2 2 6 64 64 64 14 14 14 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 7 7 7 66 66 66 59 59 59 59 59 61 86 86 86 ++99 84 50 78 66 28 152 149 142 5 5 8 122 122 122 104 96 81 ++2 2 6 2 2 6 67 67 67 14 14 14 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 5 5 5 63 63 63 24 24 24 152 149 142 175 122 13 ++238 184 12 220 170 13 226 181 52 112 86 32 194 165 151 46 46 47 ++2 2 6 2 2 6 65 65 65 17 17 17 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 5 5 5 59 59 59 21 21 21 175 122 13 231 174 11 ++240 192 13 237 183 61 240 192 13 240 192 13 234 179 16 81 64 9 ++2 2 6 2 2 6 63 63 63 25 25 25 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 5 5 5 54 54 54 51 48 39 189 138 9 238 184 12 ++240 192 13 240 192 13 240 192 13 215 161 11 207 152 19 81 64 9 ++16 16 18 5 5 8 40 40 40 44 44 44 4 4 4 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 5 5 5 59 59 59 27 27 27 126 107 64 187 136 12 ++220 170 13 201 147 20 189 138 9 198 154 46 199 182 125 70 70 70 ++27 27 27 104 96 81 12 12 14 70 70 70 16 16 16 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 17 17 17 70 70 70 12 12 12 168 168 168 174 135 135 ++175 122 13 175 122 13 178 151 83 192 191 189 233 233 233 179 179 179 ++3 3 6 29 29 31 3 3 6 41 41 41 44 44 44 5 5 5 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++8 8 8 53 53 53 44 44 44 59 59 59 238 238 238 192 191 189 ++192 191 189 192 191 189 221 205 205 240 240 240 253 253 253 253 253 253 ++70 70 70 2 2 6 2 2 6 5 5 8 67 67 67 22 22 22 ++2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 ++38 38 38 56 56 56 7 7 9 221 205 205 253 253 253 233 233 233 ++221 205 205 233 233 233 251 251 251 253 253 253 253 253 253 253 253 253 ++192 191 189 2 2 6 2 2 6 2 2 6 25 25 25 64 64 64 ++15 15 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 27 27 27 ++66 66 66 7 7 9 86 86 86 252 252 252 253 253 253 253 253 253 ++252 252 252 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++244 244 244 19 19 21 2 2 6 2 2 6 2 2 6 38 38 38 ++54 54 54 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 14 14 14 62 62 62 ++10 10 12 3 3 6 122 122 122 235 235 235 251 251 251 248 248 248 ++235 235 235 248 248 248 252 252 252 246 246 246 233 233 233 237 228 228 ++223 207 207 70 70 70 2 2 6 2 2 6 2 2 6 2 2 6 ++46 46 47 38 38 38 4 4 4 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 2 2 2 33 33 33 44 44 44 ++4 4 7 9 9 11 168 168 168 240 240 240 252 252 252 252 252 252 ++246 246 246 253 253 253 253 253 253 251 251 251 245 241 241 233 233 233 ++221 205 205 192 191 189 29 29 31 27 27 27 9 9 12 2 2 6 ++3 3 6 65 65 65 15 15 15 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 6 6 6 59 59 59 19 19 21 ++24 24 24 86 86 86 249 249 249 253 253 253 253 253 253 253 253 253 ++253 253 253 228 210 210 241 230 230 253 253 253 253 253 253 253 253 253 ++251 251 251 228 210 210 152 149 142 5 5 8 27 27 27 4 4 7 ++2 2 6 46 46 47 34 34 34 2 2 2 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 16 16 16 67 67 67 19 19 21 ++12 12 14 223 207 207 254 20 20 254 20 20 253 127 127 242 223 223 ++254 20 20 253 127 127 254 48 48 242 223 223 254 86 86 254 20 20 ++254 20 20 253 137 137 233 233 233 32 32 32 35 35 35 23 23 24 ++2 2 6 15 15 15 60 60 60 6 6 6 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 4 4 4 38 38 38 48 48 49 22 22 22 ++86 86 86 253 253 253 254 20 20 241 230 230 227 216 186 253 137 137 ++253 137 137 253 253 253 253 137 137 253 137 137 254 48 48 253 253 253 ++253 253 253 253 253 253 253 253 253 62 62 62 2 2 6 23 23 24 ++2 2 6 2 2 6 62 62 62 17 17 17 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 14 14 14 70 70 70 14 14 14 16 16 18 ++179 179 179 253 253 253 227 216 186 254 48 48 240 219 160 253 127 127 ++254 20 20 253 137 137 254 86 86 231 203 141 254 20 20 254 20 20 ++253 137 137 253 253 253 253 253 253 104 96 81 2 2 6 23 23 24 ++2 2 6 2 2 6 46 46 47 27 27 27 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 4 4 4 39 39 39 42 42 43 19 19 21 13 13 13 ++228 210 210 242 223 223 253 253 253 242 223 223 253 127 127 253 127 127 ++253 127 127 253 127 127 253 137 137 253 253 253 254 48 48 253 253 253 ++228 210 210 253 253 253 253 253 253 122 122 122 2 2 6 19 19 19 ++2 2 6 2 2 6 39 39 39 38 38 38 3 3 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 8 8 8 60 60 60 3 3 6 33 33 33 38 38 38 ++253 137 137 254 86 86 253 137 137 254 86 86 253 137 137 209 197 168 ++253 127 127 253 253 253 253 253 253 253 253 253 253 127 127 254 86 86 ++254 86 86 253 137 137 253 253 253 122 122 122 2 2 6 17 17 17 ++2 2 6 2 2 6 34 34 36 42 42 43 3 3 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 13 13 13 59 59 59 2 2 6 9 9 12 56 56 56 ++252 252 252 240 219 160 253 137 137 240 219 160 253 253 253 237 228 228 ++254 86 86 253 253 253 253 253 253 253 253 253 253 253 253 242 223 223 ++227 216 186 249 249 249 253 253 253 122 122 122 16 16 17 17 17 17 ++12 12 14 3 3 6 39 39 39 38 38 38 3 3 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 ++5 5 5 22 22 22 104 96 81 187 136 12 207 152 19 51 48 39 ++221 205 205 253 253 253 253 253 253 253 253 253 253 253 253 240 240 240 ++250 247 243 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 250 247 243 240 219 160 99 84 50 5 5 8 2 2 6 ++7 7 9 46 46 47 58 58 58 35 35 35 3 3 3 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 8 8 8 33 33 33 ++58 58 58 86 86 86 170 136 53 239 182 13 246 190 14 220 170 13 ++44 38 29 179 179 179 253 253 253 253 253 253 253 253 253 240 240 240 ++253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 240 219 160 240 192 13 112 86 32 2 2 6 2 2 6 ++3 3 6 41 33 20 220 170 13 53 53 53 4 4 4 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 2 2 2 32 32 32 150 116 44 ++215 161 11 215 161 11 228 170 11 245 188 14 246 190 14 246 190 14 ++187 136 12 9 9 11 122 122 122 251 251 251 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++248 248 248 211 196 135 239 182 13 175 122 13 6 5 6 2 2 6 ++16 14 12 187 136 12 238 184 12 84 78 65 10 10 10 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 4 4 4 53 53 53 207 152 19 ++242 185 13 245 188 14 246 190 14 246 190 14 246 190 14 246 190 14 ++240 192 13 81 64 9 2 2 6 86 86 86 244 244 244 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++233 233 233 199 182 125 231 174 11 207 152 19 175 122 13 175 122 13 ++201 147 20 239 182 13 244 187 14 150 116 44 35 35 35 6 6 6 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 5 5 5 53 53 53 201 147 20 ++242 185 13 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 220 170 13 13 11 10 2 2 6 152 149 142 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++235 235 235 199 182 125 228 170 11 234 177 12 226 168 11 226 168 11 ++234 177 12 246 190 14 246 190 14 234 179 16 126 107 64 36 36 36 ++6 6 6 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 3 3 3 48 48 49 189 142 35 ++242 185 13 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 140 112 39 36 36 36 192 191 189 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 253 ++192 191 189 112 86 32 226 168 11 244 187 14 244 187 14 244 187 14 ++245 188 14 246 190 14 246 190 14 246 190 14 242 185 13 150 116 44 ++27 27 27 2 2 2 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 6 6 6 58 58 58 189 142 35 ++239 182 13 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 239 188 14 209 197 168 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 252 252 252 168 168 168 ++16 16 18 97 67 8 228 170 11 245 188 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 244 187 14 198 154 46 ++35 35 35 3 3 3 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 13 13 13 84 78 65 215 161 11 ++244 187 14 246 190 14 246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 238 184 12 187 136 12 168 168 168 244 244 244 ++253 253 253 252 252 252 240 240 240 179 179 179 67 67 67 2 2 6 ++2 2 6 97 67 8 228 170 11 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 245 188 14 234 177 12 189 142 35 86 77 61 ++16 16 16 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 13 13 13 103 92 56 207 152 19 ++228 170 11 234 177 12 239 182 13 242 186 14 245 188 14 246 190 14 ++246 190 14 246 190 14 239 182 13 189 138 9 41 33 20 10 10 12 ++30 30 31 23 23 24 5 5 8 2 2 6 2 2 6 2 2 6 ++4 4 6 112 86 32 215 161 11 245 188 14 246 190 14 245 188 14 ++239 182 13 228 170 11 189 142 35 104 96 81 48 48 49 17 17 17 ++2 2 2 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 5 5 5 39 39 39 103 92 56 ++141 109 44 175 122 13 187 136 12 189 138 9 207 152 19 228 170 11 ++239 182 13 239 182 13 215 161 11 175 122 13 41 33 20 2 2 6 ++15 15 17 20 20 22 20 20 22 20 20 22 20 20 22 8 8 10 ++4 4 6 97 67 8 189 138 9 231 174 11 239 182 13 226 168 11 ++189 138 9 126 107 64 59 59 59 21 21 21 5 5 5 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 17 17 17 ++34 34 34 57 57 57 84 78 65 103 92 56 125 101 41 140 112 39 ++175 122 13 175 122 13 175 122 13 97 67 8 72 67 58 84 78 65 ++60 60 60 56 56 56 56 56 56 56 56 56 57 57 57 65 65 65 ++86 86 86 95 73 34 175 122 13 187 136 12 187 136 12 175 122 13 ++103 92 56 41 41 41 10 10 10 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++2 2 2 4 4 4 12 12 12 24 24 24 40 40 40 70 70 70 ++86 77 61 95 73 34 88 72 41 72 67 58 36 36 36 10 10 10 ++5 5 5 5 5 5 5 5 5 4 4 4 5 5 5 6 6 6 ++22 22 22 61 61 59 88 72 41 112 86 32 112 86 32 84 78 65 ++32 32 32 6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 10 10 10 ++21 21 21 33 33 33 31 31 31 16 16 16 2 2 2 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++2 2 2 12 12 12 30 30 31 40 40 40 32 32 32 16 16 16 ++2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++0 0 0 0 0 0 0 0 0 0 0 0 +--- ps3-linux-2.6.21.orig/include/linux/linux_logo.h ++++ ps3-linux-2.6.21/include/linux/linux_logo.h +@@ -44,6 +44,7 @@ extern const struct linux_logo logo_supe + extern const struct linux_logo logo_superh_vga16; + extern const struct linux_logo logo_superh_clut224; + extern const struct linux_logo logo_m32r_clut224; ++extern const struct linux_logo logo_spe_clut224; + + extern const struct linux_logo *fb_find_logo(int depth); + #ifdef CONFIG_LOGO --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/13-ps3-system-bus-add-modinfo-attribute.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/13-ps3-system-bus-add-modinfo-attribute.patch @@ -0,0 +1,44 @@ +Subject: PS3: System-bus modinfo attribute +From: David Woodhouse + +Add modinfo attribute to ps3_system_bus devices. Also make them all +children of the same ps3_system_bus 'device' so they appear in a +corresponding subdirectory under /sys/devices + +Signed-off-by: David Woodhouse +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/system-bus.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/arch/powerpc/platforms/ps3/system-bus.c ++++ b/arch/powerpc/platforms/ps3/system-bus.c +@@ -448,6 +448,20 @@ static int ps3_system_bus_uevent(struct + return 0; + } + ++static ssize_t modalias_show(struct device *_dev, struct device_attribute *a, ++ char *buf) ++{ ++ struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); ++ int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id); ++ ++ return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; ++} ++ ++static struct device_attribute ps3_system_bus_dev_attrs[] = { ++ __ATTR_RO(modalias), ++ __ATTR_NULL, ++}; ++ + struct bus_type ps3_system_bus_type = { + .name = "ps3_system_bus", + .match = ps3_system_bus_match, +@@ -455,6 +469,7 @@ struct bus_type ps3_system_bus_type = { + .probe = ps3_system_bus_probe, + .remove = ps3_system_bus_remove, + .shutdown = ps3_system_bus_shutdown, ++ .dev_attrs = ps3_system_bus_dev_attrs, + }; + + static int __init ps3_system_bus_init(void) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/08-ps3-move-chip-routines-up.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/08-ps3-move-chip-routines-up.patch @@ -0,0 +1,175 @@ +Subject: PS3: Move chip mask defs up + +This just moves the definitions of the PS3 chip_mask routines up +above the irq setup routines. This change is needed for the +kexec updates that follow. Also adds some inline documentation +to the routines. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/interrupt.c | 147 +++++++++++++++++++-------------- + 1 file changed, 86 insertions(+), 61 deletions(-) + +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -91,6 +91,92 @@ struct ps3_private { + static DEFINE_PER_CPU(struct ps3_private, ps3_private); + + /** ++ * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp. ++ * @virq: The assigned Linux virq. ++ * ++ * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask(). ++ */ ++ ++static void ps3_chip_mask(unsigned int virq) ++{ ++ struct ps3_private *pd = get_irq_chip_data(virq); ++ u64 bit = 0x8000000000000000UL >> virq; ++ u64 *p = &pd->bmp.mask; ++ u64 old; ++ unsigned long flags; ++ ++ pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); ++ ++ local_irq_save(flags); ++ asm volatile( ++ "1: ldarx %0,0,%3\n" ++ "andc %0,%0,%2\n" ++ "stdcx. %0,0,%3\n" ++ "bne- 1b" ++ : "=&r" (old), "+m" (*p) ++ : "r" (bit), "r" (p) ++ : "cc" ); ++ ++ lv1_did_update_interrupt_mask(pd->node, pd->cpu); ++ local_irq_restore(flags); ++} ++ ++/** ++ * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp. ++ * @virq: The assigned Linux virq. ++ * ++ * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask(). ++ */ ++ ++static void ps3_chip_unmask(unsigned int virq) ++{ ++ struct ps3_private *pd = get_irq_chip_data(virq); ++ u64 bit = 0x8000000000000000UL >> virq; ++ u64 *p = &pd->bmp.mask; ++ u64 old; ++ unsigned long flags; ++ ++ pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); ++ ++ local_irq_save(flags); ++ asm volatile( ++ "1: ldarx %0,0,%3\n" ++ "or %0,%0,%2\n" ++ "stdcx. %0,0,%3\n" ++ "bne- 1b" ++ : "=&r" (old), "+m" (*p) ++ : "r" (bit), "r" (p) ++ : "cc" ); ++ ++ lv1_did_update_interrupt_mask(pd->node, pd->cpu); ++ local_irq_restore(flags); ++} ++ ++/** ++ * ps3_chip_eoi - HV end-of-interrupt. ++ * @virq: The assigned Linux virq. ++ * ++ * Calls lv1_end_of_interrupt_ext(). ++ */ ++ ++static void ps3_chip_eoi(unsigned int virq) ++{ ++ const struct ps3_private *pd = get_irq_chip_data(virq); ++ lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq); ++} ++ ++/** ++ * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip. ++ */ ++ ++static struct irq_chip ps3_irq_chip = { ++ .typename = "ps3", ++ .mask = ps3_chip_mask, ++ .unmask = ps3_chip_unmask, ++ .eoi = ps3_chip_eoi, ++}; ++ ++/** + * ps3_virq_setup - virq related setup. + * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be + * serviced on. +@@ -565,67 +651,6 @@ static void __maybe_unused _dump_mask(st + static void dump_bmp(struct ps3_private* pd) {}; + #endif /* defined(DEBUG) */ + +-static void ps3_chip_mask(unsigned int virq) +-{ +- struct ps3_private *pd = get_irq_chip_data(virq); +- u64 bit = 0x8000000000000000UL >> virq; +- u64 *p = &pd->bmp.mask; +- u64 old; +- unsigned long flags; +- +- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); +- +- local_irq_save(flags); +- asm volatile( +- "1: ldarx %0,0,%3\n" +- "andc %0,%0,%2\n" +- "stdcx. %0,0,%3\n" +- "bne- 1b" +- : "=&r" (old), "+m" (*p) +- : "r" (bit), "r" (p) +- : "cc" ); +- +- lv1_did_update_interrupt_mask(pd->node, pd->cpu); +- local_irq_restore(flags); +-} +- +-static void ps3_chip_unmask(unsigned int virq) +-{ +- struct ps3_private *pd = get_irq_chip_data(virq); +- u64 bit = 0x8000000000000000UL >> virq; +- u64 *p = &pd->bmp.mask; +- u64 old; +- unsigned long flags; +- +- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); +- +- local_irq_save(flags); +- asm volatile( +- "1: ldarx %0,0,%3\n" +- "or %0,%0,%2\n" +- "stdcx. %0,0,%3\n" +- "bne- 1b" +- : "=&r" (old), "+m" (*p) +- : "r" (bit), "r" (p) +- : "cc" ); +- +- lv1_did_update_interrupt_mask(pd->node, pd->cpu); +- local_irq_restore(flags); +-} +- +-static void ps3_chip_eoi(unsigned int virq) +-{ +- const struct ps3_private *pd = get_irq_chip_data(virq); +- lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq); +-} +- +-static struct irq_chip irq_chip = { +- .typename = "ps3", +- .mask = ps3_chip_mask, +- .unmask = ps3_chip_unmask, +- .eoi = ps3_chip_eoi, +-}; +- + static void ps3_host_unmap(struct irq_host *h, unsigned int virq) + { + set_irq_chip_data(virq, NULL); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/17-ps3-system-bus-rework-vuart.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/17-ps3-system-bus-rework-vuart.patch @@ -0,0 +1,1545 @@ +Subject: PS3: Vuart rework + +PS3 vuart updates to reflect the new PS3 unified device support. + - Move vuart devices to the PS3 system bus. + - Replace use of ps3_vuart_port_device with ps3_system_bus_device. + - Make the PS3 vuart bus driver a loadable module. + - Add remove() and shutdown() routines. + - Move ps3_vuart_work into ps3_vuart_port_priv.tx_list. + - Remove redundant spinlock ps3_vuart_work.lock. + - No longer free ps3_vuart_port_device.priv on shutdown. + - Cleanup Kconfig defs. + - Export symbols needed for modular port drivers. + - Arrange to use port numbers found in repository. + - Fix bugs in ps3_vuart_read_async() and polled reading + - Cleanup handling of shared interrupt with ps3_vuart_bus_interrupt_get() + and ps3_vuart_bus_interrupt_put() + - Add more comments to vuart.c. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/Kconfig | 21 + arch/powerpc/platforms/ps3/interrupt.c | 2 + drivers/ps3/vuart.c | 813 +++++++++++++++++++-------------- + drivers/ps3/vuart.h | 71 -- + include/asm-powerpc/ps3.h | 17 + 5 files changed, 520 insertions(+), 404 deletions(-) + +--- a/arch/powerpc/platforms/ps3/Kconfig ++++ b/arch/powerpc/platforms/ps3/Kconfig +@@ -73,18 +73,12 @@ config PS3_USE_LPAR_ADDR + + config PS3_VUART + depends on PPC_PS3 +- bool "PS3 Virtual UART support" if PS3_ADVANCED +- default y +- help +- Include support for the PS3 Virtual UART. +- +- This support is required for several system services +- including the System Manager and AV Settings. In +- general, all users will say Y. ++ tristate + + config PS3_PS3AV ++ depends on PPC_PS3 + tristate "PS3 AV settings driver" if PS3_ADVANCED +- depends on PS3_VUART ++ select PS3_VUART + default y + help + Include support for the PS3 AV Settings driver. +@@ -93,13 +87,14 @@ config PS3_PS3AV + general, all users will say Y or M. + + config PS3_SYS_MANAGER +- bool "PS3 System Manager driver" if PS3_ADVANCED +- depends on PS3_VUART +- default y ++ depends on PPC_PS3 ++ tristate "PS3 System Manager driver" if PS3_ADVANCED ++ select PS3_VUART ++ default m + help + Include support for the PS3 System Manager. + + This support is required for system control. In +- general, all users will say Y. ++ general, all users will say Y or M. + + endmenu +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -565,6 +565,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_bin + + return result; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup); + + int ps3_vuart_irq_destroy(unsigned int virq) + { +@@ -584,6 +585,7 @@ int ps3_vuart_irq_destroy(unsigned int v + + return result; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy); + + /** + * ps3_spe_irq_setup - Setup an spe virq. +--- a/drivers/ps3/vuart.c ++++ b/drivers/ps3/vuart.c +@@ -71,6 +71,34 @@ enum vuart_interrupt_mask { + }; + + /** ++ * struct ps3_vuart_port_priv - private vuart device data. ++ */ ++ ++struct ps3_vuart_port_priv { ++ u64 interrupt_mask; ++ ++ struct { ++ spinlock_t lock; ++ struct list_head head; ++ } tx_list; ++ struct { ++ struct ps3_vuart_work work; ++ unsigned long bytes_held; ++ spinlock_t lock; ++ struct list_head head; ++ } rx_list; ++ struct ps3_vuart_stats stats; ++}; ++ ++static struct ps3_vuart_port_priv *to_port_priv( ++ struct ps3_system_bus_device *dev) ++{ ++ BUG_ON(!dev); ++ BUG_ON(!dev->driver_priv); ++ return (struct ps3_vuart_port_priv *)dev->driver_priv; ++} ++ ++/** + * struct ports_bmp - bitmap indicating ports needing service. + * + * A 256 bit read only bitmap indicating ports needing service. Do not write +@@ -89,23 +117,6 @@ static void __maybe_unused _dump_ports_b + pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); + } + +-static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id, +- unsigned int *port_number) +-{ +- switch(match_id) { +- case PS3_MATCH_ID_AV_SETTINGS: +- *port_number = 0; +- return 0; +- case PS3_MATCH_ID_SYSTEM_MANAGER: +- *port_number = 2; +- return 0; +- default: +- WARN_ON(1); +- *port_number = UINT_MAX; +- return -EINVAL; +- }; +-} +- + #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) + static void __maybe_unused _dump_port_params(unsigned int port_number, + const char* func, int line) +@@ -144,14 +155,14 @@ struct vuart_triggers { + unsigned long tx; + }; + +-int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev, ++int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev, + struct vuart_triggers *trig) + { + int result; + unsigned long size; + unsigned long val; + +- result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_TX_TRIGGER, &trig->tx); + + if (result) { +@@ -160,7 +171,7 @@ int ps3_vuart_get_triggers(struct ps3_vu + return result; + } + +- result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_RX_BUF_SIZE, &size); + + if (result) { +@@ -169,7 +180,7 @@ int ps3_vuart_get_triggers(struct ps3_vu + return result; + } + +- result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_RX_TRIGGER, &val); + + if (result) { +@@ -186,13 +197,13 @@ int ps3_vuart_get_triggers(struct ps3_vu + return result; + } + +-int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx, ++int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx, + unsigned int rx) + { + int result; + unsigned long size; + +- result = lv1_set_virtual_uart_param(dev->priv->port_number, ++ result = lv1_set_virtual_uart_param(dev->port_number, + PARAM_TX_TRIGGER, tx); + + if (result) { +@@ -201,7 +212,7 @@ int ps3_vuart_set_triggers(struct ps3_vu + return result; + } + +- result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_RX_BUF_SIZE, &size); + + if (result) { +@@ -210,7 +221,7 @@ int ps3_vuart_set_triggers(struct ps3_vu + return result; + } + +- result = lv1_set_virtual_uart_param(dev->priv->port_number, ++ result = lv1_set_virtual_uart_param(dev->port_number, + PARAM_RX_TRIGGER, size - rx); + + if (result) { +@@ -225,10 +236,12 @@ int ps3_vuart_set_triggers(struct ps3_vu + return result; + } + +-static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, ++static int ps3_vuart_get_rx_bytes_waiting(struct ps3_system_bus_device *dev, + u64 *bytes_waiting) + { +- int result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ int result; ++ ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_RX_BYTES, bytes_waiting); + + if (result) +@@ -240,17 +253,24 @@ static int ps3_vuart_get_rx_bytes_waitin + return result; + } + +-static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev, ++/** ++ * ps3_vuart_set_interrupt_mask - Enable/disable the port interrupt sources. ++ * @dev: The struct ps3_system_bus_device instance. ++ * @bmp: Logical OR of enum vuart_interrupt_mask values. A zero bit disables. ++ */ ++ ++static int ps3_vuart_set_interrupt_mask(struct ps3_system_bus_device *dev, + unsigned long mask) + { + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + + dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); + +- dev->priv->interrupt_mask = mask; ++ priv->interrupt_mask = mask; + +- result = lv1_set_virtual_uart_param(dev->priv->port_number, +- PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask); ++ result = lv1_set_virtual_uart_param(dev->port_number, ++ PARAM_INTERRUPT_MASK, priv->interrupt_mask); + + if (result) + dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", +@@ -259,79 +279,96 @@ static int ps3_vuart_set_interrupt_mask( + return result; + } + +-static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev, ++static int ps3_vuart_get_interrupt_status(struct ps3_system_bus_device *dev, + unsigned long *status) + { ++ int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + u64 tmp; +- int result = lv1_get_virtual_uart_param(dev->priv->port_number, ++ ++ result = lv1_get_virtual_uart_param(dev->port_number, + PARAM_INTERRUPT_STATUS, &tmp); + + if (result) + dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", + __func__, __LINE__, ps3_result(result)); + +- *status = tmp & dev->priv->interrupt_mask; ++ *status = tmp & priv->interrupt_mask; + + dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", +- __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status); ++ __func__, __LINE__, priv->interrupt_mask, tmp, *status); + + return result; + } + +-int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) ++int ps3_vuart_enable_interrupt_tx(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0 +- : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0 ++ : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + | INTERRUPT_MASK_TX); + } + +-int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) ++int ps3_vuart_enable_interrupt_rx(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0 +- : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0 ++ : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + | INTERRUPT_MASK_RX); + } + +-int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) ++int ps3_vuart_enable_interrupt_disconnect(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 +- : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 ++ : ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + | INTERRUPT_MASK_DISCONNECT); + } + +-int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) ++int ps3_vuart_disable_interrupt_tx(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) +- ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_TX) ++ ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + & ~INTERRUPT_MASK_TX) : 0; + } + +-int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) ++int ps3_vuart_disable_interrupt_rx(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) +- ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_RX) ++ ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + & ~INTERRUPT_MASK_RX) : 0; + } + +-int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) ++int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev) + { +- return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) +- ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ ++ return (priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ++ ? ps3_vuart_set_interrupt_mask(dev, priv->interrupt_mask + & ~INTERRUPT_MASK_DISCONNECT) : 0; + } + + /** + * ps3_vuart_raw_write - Low level write helper. ++ * @dev: The struct ps3_system_bus_device instance. + * + * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write. + */ + +-static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev, ++static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, + const void* buf, unsigned int bytes, unsigned long *bytes_written) + { + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + +- result = lv1_write_virtual_uart(dev->priv->port_number, ++ result = lv1_write_virtual_uart(dev->port_number, + ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written); + + if (result) { +@@ -340,28 +377,30 @@ static int ps3_vuart_raw_write(struct ps + return result; + } + +- dev->priv->stats.bytes_written += *bytes_written; ++ priv->stats.bytes_written += *bytes_written; + + dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__, +- *bytes_written, bytes, dev->priv->stats.bytes_written); ++ *bytes_written, bytes, priv->stats.bytes_written); + + return result; + } + + /** + * ps3_vuart_raw_read - Low level read helper. ++ * @dev: The struct ps3_system_bus_device instance. + * + * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read. + */ + +-static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf, ++static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void* buf, + unsigned int bytes, unsigned long *bytes_read) + { + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + + dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); + +- result = lv1_read_virtual_uart(dev->priv->port_number, ++ result = lv1_read_virtual_uart(dev->port_number, + ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); + + if (result) { +@@ -370,25 +409,27 @@ static int ps3_vuart_raw_read(struct ps3 + return result; + } + +- dev->priv->stats.bytes_read += *bytes_read; ++ priv->stats.bytes_read += *bytes_read; + + dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, +- *bytes_read, bytes, dev->priv->stats.bytes_read); ++ *bytes_read, bytes, priv->stats.bytes_read); + + return result; + } + + /** + * ps3_vuart_clear_rx_bytes - Discard bytes received. ++ * @dev: The struct ps3_system_bus_device instance. + * @bytes: Max byte count to discard, zero = all pending. + * + * Used to clear pending rx interrupt source. Will not block. + */ + +-void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev, ++void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev, + unsigned int bytes) + { + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + u64 bytes_waiting; + void* tmp; + +@@ -418,8 +459,9 @@ void ps3_vuart_clear_rx_bytes(struct ps3 + + /* Don't include these bytes in the stats. */ + +- dev->priv->stats.bytes_read -= bytes_waiting; ++ priv->stats.bytes_read -= bytes_waiting; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_clear_rx_bytes); + + /** + * struct list_buffer - An element for a port device fifo buffer list. +@@ -435,6 +477,7 @@ struct list_buffer { + + /** + * ps3_vuart_write - the entry point for writing data to a port ++ * @dev: The struct ps3_system_bus_device instance. + * + * If the port is idle on entry as much of the incoming data is written to + * the port as the port will accept. Otherwise a list buffer is created +@@ -442,25 +485,26 @@ struct list_buffer { + * then enqueued for transmision via the transmit interrupt. + */ + +-int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, ++int ps3_vuart_write(struct ps3_system_bus_device *dev, const void* buf, + unsigned int bytes) + { + static unsigned long dbg_number; + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long flags; + struct list_buffer *lb; + + dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, + bytes, bytes); + +- spin_lock_irqsave(&dev->priv->tx_list.lock, flags); ++ spin_lock_irqsave(&priv->tx_list.lock, flags); + +- if (list_empty(&dev->priv->tx_list.head)) { ++ if (list_empty(&priv->tx_list.head)) { + unsigned long bytes_written; + + result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); + +- spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->tx_list.lock, flags); + + if (result) { + dev_dbg(&dev->core, +@@ -478,7 +522,7 @@ int ps3_vuart_write(struct ps3_vuart_por + bytes -= bytes_written; + buf += bytes_written; + } else +- spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->tx_list.lock, flags); + + lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); + +@@ -491,29 +535,86 @@ int ps3_vuart_write(struct ps3_vuart_por + lb->tail = lb->data + bytes; + lb->dbg_number = ++dbg_number; + +- spin_lock_irqsave(&dev->priv->tx_list.lock, flags); +- list_add_tail(&lb->link, &dev->priv->tx_list.head); ++ spin_lock_irqsave(&priv->tx_list.lock, flags); ++ list_add_tail(&lb->link, &priv->tx_list.head); + ps3_vuart_enable_interrupt_tx(dev); +- spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->tx_list.lock, flags); + + dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", + __func__, __LINE__, lb->dbg_number, bytes); + + return 0; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_write); ++ ++/** ++ * ps3_vuart_queue_rx_bytes - Queue waiting bytes into the buffer list. ++ * @dev: The struct ps3_system_bus_device instance. ++ * @bytes_queued: Number of bytes queued to the buffer list. ++ * ++ * Must be called with priv->rx_list.lock held. ++ */ ++ ++static int ps3_vuart_queue_rx_bytes(struct ps3_system_bus_device *dev, ++ u64 *bytes_queued) ++{ ++ static unsigned long dbg_number; ++ int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ struct list_buffer *lb; ++ u64 bytes; ++ ++ *bytes_queued = 0; ++ ++ result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes); ++ BUG_ON(result); ++ ++ if (result) ++ return -EIO; ++ ++ if(!bytes) ++ return 0; ++ ++ /* Add some extra space for recently arrived data. */ ++ ++ bytes += 128; ++ ++ lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC); ++ ++ if (!lb) ++ return -ENOMEM; ++ ++ ps3_vuart_raw_read(dev, lb->data, bytes, &bytes); ++ ++ lb->head = lb->data; ++ lb->tail = lb->data + bytes; ++ lb->dbg_number = ++dbg_number; ++ ++ list_add_tail(&lb->link, &priv->rx_list.head); ++ priv->rx_list.bytes_held += bytes; ++ ++ dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n", ++ __func__, __LINE__, lb->dbg_number, bytes); ++ ++ *bytes_queued = bytes; ++ ++ return 0; ++} + + /** +- * ps3_vuart_read - the entry point for reading data from a port ++ * ps3_vuart_read - The entry point for reading data from a port. + * +- * If enough bytes to satisfy the request are held in the buffer list those +- * bytes are dequeued and copied to the caller's buffer. Emptied list buffers +- * are retiered. If the request cannot be statified by bytes held in the list +- * buffers -EAGAIN is returned. ++ * Queue data waiting at the port, and if enough bytes to satisfy the request ++ * are held in the buffer list those bytes are dequeued and copied to the ++ * caller's buffer. Emptied list buffers are retiered. If the request cannot ++ * be statified by bytes held in the list buffers -EAGAIN is returned. + */ + +-int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, ++int ps3_vuart_read(struct ps3_system_bus_device *dev, void* buf, + unsigned int bytes) + { ++ int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long flags; + struct list_buffer *lb, *n; + unsigned long bytes_read; +@@ -521,30 +622,37 @@ int ps3_vuart_read(struct ps3_vuart_port + dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, + bytes, bytes); + +- spin_lock_irqsave(&dev->priv->rx_list.lock, flags); ++ spin_lock_irqsave(&priv->rx_list.lock, flags); + +- if (dev->priv->rx_list.bytes_held < bytes) { +- spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); +- dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", +- __func__, __LINE__, +- bytes - dev->priv->rx_list.bytes_held); +- return -EAGAIN; ++ /* Queue rx bytes here for polled reads. */ ++ ++ while (priv->rx_list.bytes_held < bytes) { ++ u64 tmp; ++ ++ result = ps3_vuart_queue_rx_bytes(dev, &tmp); ++ if (result || !tmp) { ++ dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", ++ __func__, __LINE__, ++ bytes - priv->rx_list.bytes_held); ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); ++ return -EAGAIN; ++ } + } + +- list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) { ++ list_for_each_entry_safe(lb, n, &priv->rx_list.head, link) { + bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); + + memcpy(buf, lb->head, bytes_read); + buf += bytes_read; + bytes -= bytes_read; +- dev->priv->rx_list.bytes_held -= bytes_read; ++ priv->rx_list.bytes_held -= bytes_read; + + if (bytes_read < lb->tail - lb->head) { + lb->head += bytes_read; + dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh " + "bytes\n", __func__, __LINE__, lb->dbg_number, + bytes_read); +- spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); + return 0; + } + +@@ -556,16 +664,32 @@ int ps3_vuart_read(struct ps3_vuart_port + kfree(lb); + } + +- spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); + return 0; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_read); + +-int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func, +- unsigned int bytes) ++/** ++ * ps3_vuart_work - Asynchronous read handler. ++ */ ++ ++static void ps3_vuart_work(struct work_struct *work) ++{ ++ struct ps3_system_bus_device *dev = ++ ps3_vuart_work_to_system_bus_dev(work); ++ struct ps3_vuart_port_driver *drv = ++ ps3_system_bus_dev_to_vuart_drv(dev); ++ ++ BUG_ON(!drv); ++ drv->work(dev); ++} ++ ++int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes) + { ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long flags; + +- if(dev->priv->work.trigger) { ++ if(priv->rx_list.work.trigger) { + dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n", + __func__, __LINE__); + return -EAGAIN; +@@ -573,30 +697,32 @@ int ps3_vuart_read_async(struct ps3_vuar + + BUG_ON(!bytes); + +- PREPARE_WORK(&dev->priv->work.work, func); ++ PREPARE_WORK(&priv->rx_list.work.work, ps3_vuart_work); + +- spin_lock_irqsave(&dev->priv->work.lock, flags); +- if(dev->priv->rx_list.bytes_held >= bytes) { ++ spin_lock_irqsave(&priv->rx_list.lock, flags); ++ if(priv->rx_list.bytes_held >= bytes) { + dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n", + __func__, __LINE__, bytes); +- schedule_work(&dev->priv->work.work); +- spin_unlock_irqrestore(&dev->priv->work.lock, flags); ++ schedule_work(&priv->rx_list.work.work); ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); + return 0; + } + +- dev->priv->work.trigger = bytes; +- spin_unlock_irqrestore(&dev->priv->work.lock, flags); ++ priv->rx_list.work.trigger = bytes; ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); + + dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__, + __LINE__, bytes, bytes); + + return 0; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_read_async); + +-void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev) ++void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev) + { +- dev->priv->work.trigger = 0; ++ to_port_priv(dev)->rx_list.work.trigger = 0; + } ++EXPORT_SYMBOL_GPL(ps3_vuart_cancel_async); + + /** + * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler +@@ -606,18 +732,19 @@ void ps3_vuart_cancel_async(struct ps3_v + * adjusts the final list buffer state for a partial write. + */ + +-static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev) ++static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev) + { + int result = 0; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long flags; + struct list_buffer *lb, *n; + unsigned long bytes_total = 0; + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + +- spin_lock_irqsave(&dev->priv->tx_list.lock, flags); ++ spin_lock_irqsave(&priv->tx_list.lock, flags); + +- list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) { ++ list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) { + + unsigned long bytes_written; + +@@ -651,7 +778,7 @@ static int ps3_vuart_handle_interrupt_tx + + ps3_vuart_disable_interrupt_tx(dev); + port_full: +- spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags); ++ spin_unlock_irqrestore(&priv->tx_list.lock, flags); + dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", + __func__, __LINE__, bytes_total); + return result; +@@ -665,60 +792,37 @@ port_full: + * buffer list. Buffer list data is dequeued via ps3_vuart_read. + */ + +-static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev) ++static int ps3_vuart_handle_interrupt_rx(struct ps3_system_bus_device *dev) + { +- static unsigned long dbg_number; +- int result = 0; ++ int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long flags; +- struct list_buffer *lb; +- unsigned long bytes; ++ u64 bytes; + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + +- result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes); +- +- if (result) +- return -EIO; +- +- BUG_ON(!bytes); +- +- /* Add some extra space for recently arrived data. */ +- +- bytes += 128; +- +- lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC); ++ spin_lock_irqsave(&priv->rx_list.lock, flags); ++ result = ps3_vuart_queue_rx_bytes(dev, &bytes); + +- if (!lb) +- return -ENOMEM; +- +- ps3_vuart_raw_read(dev, lb->data, bytes, &bytes); +- +- lb->head = lb->data; +- lb->tail = lb->data + bytes; +- lb->dbg_number = ++dbg_number; +- +- spin_lock_irqsave(&dev->priv->rx_list.lock, flags); +- list_add_tail(&lb->link, &dev->priv->rx_list.head); +- dev->priv->rx_list.bytes_held += bytes; +- spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags); +- +- dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n", +- __func__, __LINE__, lb->dbg_number, bytes); ++ if (result) { ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); ++ return result; ++ } + +- spin_lock_irqsave(&dev->priv->work.lock, flags); +- if(dev->priv->work.trigger +- && dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) { ++ if(priv->rx_list.work.trigger && priv->rx_list.bytes_held ++ >= priv->rx_list.work.trigger) { + dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n", +- __func__, __LINE__, dev->priv->work.trigger); +- dev->priv->work.trigger = 0; +- schedule_work(&dev->priv->work.work); ++ __func__, __LINE__, priv->rx_list.work.trigger); ++ priv->rx_list.work.trigger = 0; ++ schedule_work(&priv->rx_list.work.work); + } +- spin_unlock_irqrestore(&dev->priv->work.lock, flags); +- return 0; ++ ++ spin_unlock_irqrestore(&priv->rx_list.lock, flags); ++ return result; + } + + static int ps3_vuart_handle_interrupt_disconnect( +- struct ps3_vuart_port_device *dev) ++ struct ps3_system_bus_device *dev) + { + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + BUG_ON("no support"); +@@ -733,9 +837,10 @@ static int ps3_vuart_handle_interrupt_di + * stage handler after one iteration. + */ + +-static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev) ++static int ps3_vuart_handle_port_interrupt(struct ps3_system_bus_device *dev) + { + int result; ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); + unsigned long status; + + result = ps3_vuart_get_interrupt_status(dev, &status); +@@ -747,21 +852,21 @@ static int ps3_vuart_handle_port_interru + status); + + if (status & INTERRUPT_MASK_DISCONNECT) { +- dev->priv->stats.disconnect_interrupts++; ++ priv->stats.disconnect_interrupts++; + result = ps3_vuart_handle_interrupt_disconnect(dev); + if (result) + ps3_vuart_disable_interrupt_disconnect(dev); + } + + if (status & INTERRUPT_MASK_TX) { +- dev->priv->stats.tx_interrupts++; ++ priv->stats.tx_interrupts++; + result = ps3_vuart_handle_interrupt_tx(dev); + if (result) + ps3_vuart_disable_interrupt_tx(dev); + } + + if (status & INTERRUPT_MASK_RX) { +- dev->priv->stats.rx_interrupts++; ++ priv->stats.rx_interrupts++; + result = ps3_vuart_handle_interrupt_rx(dev); + if (result) + ps3_vuart_disable_interrupt_rx(dev); +@@ -771,11 +876,11 @@ static int ps3_vuart_handle_port_interru + } + + struct vuart_bus_priv { +- const struct ports_bmp bmp; ++ struct ports_bmp* bmp; + unsigned int virq; + struct semaphore probe_mutex; + int use_count; +- struct ps3_vuart_port_device *devices[PORT_COUNT]; ++ struct ps3_system_bus_device *devices[PORT_COUNT]; + } static vuart_bus_priv; + + /** +@@ -788,17 +893,16 @@ struct vuart_bus_priv { + + static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) + { +- struct vuart_bus_priv *bus_priv; ++ struct vuart_bus_priv *bus_priv = _private; + +- BUG_ON(!_private); +- bus_priv = (struct vuart_bus_priv *)_private; ++ BUG_ON(!bus_priv); + + while (1) { + unsigned int port; + +- dump_ports_bmp(&bus_priv->bmp); ++ dump_ports_bmp(bus_priv->bmp); + +- port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status); ++ port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp->status); + + if (port == BITS_PER_LONG) + break; +@@ -812,100 +916,144 @@ static irqreturn_t ps3_vuart_irq_handler + return IRQ_HANDLED; + } + +-static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv) ++static int ps3_vuart_bus_interrupt_get(void) + { + int result; +- struct ps3_vuart_port_driver *drv = to_ps3_vuart_port_driver(_drv); +- struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); + +- result = dev->match_id == drv->match_id; ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ vuart_bus_priv.use_count++; ++ ++ BUG_ON(vuart_bus_priv.use_count > 2); ++ ++ if (vuart_bus_priv.use_count != 1) { ++ return 0; ++ } ++ ++ BUG_ON(vuart_bus_priv.bmp); ++ ++ vuart_bus_priv.bmp = kzalloc(sizeof(struct ports_bmp), GFP_KERNEL); ++ ++ if (!vuart_bus_priv.bmp) { ++ pr_debug("%s:%d: kzalloc failed.\n", __func__, __LINE__); ++ result = -ENOMEM; ++ goto fail_bmp_malloc; ++ } ++ ++ result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, vuart_bus_priv.bmp, ++ &vuart_bus_priv.virq); ++ ++ if (result) { ++ pr_debug("%s:%d: ps3_vuart_irq_setup failed (%d)\n", ++ __func__, __LINE__, result); ++ result = -EPERM; ++ goto fail_alloc_irq; ++ } ++ ++ result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, ++ IRQF_DISABLED, "vuart", &vuart_bus_priv); + +- dev_info(&dev->core, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, +- __LINE__, dev->match_id, dev->core.bus_id, drv->match_id, +- drv->core.name, (result ? "match" : "miss")); ++ if (result) { ++ pr_debug("%s:%d: request_irq failed (%d)\n", ++ __func__, __LINE__, result); ++ goto fail_request_irq; ++ } + ++ pr_debug(" <- %s:%d: ok\n", __func__, __LINE__); + return result; ++ ++fail_request_irq: ++ ps3_vuart_irq_destroy(vuart_bus_priv.virq); ++ vuart_bus_priv.virq = NO_IRQ; ++fail_alloc_irq: ++ kfree(vuart_bus_priv.bmp); ++ vuart_bus_priv.bmp = NULL; ++fail_bmp_malloc: ++ vuart_bus_priv.use_count--; ++ pr_debug(" <- %s:%d: failed\n", __func__, __LINE__); ++ return result; ++} ++ ++static int ps3_vuart_bus_interrupt_put(void) ++{ ++ pr_debug(" -> %s:%d\n", __func__, __LINE__); ++ ++ vuart_bus_priv.use_count--; ++ ++ BUG_ON(vuart_bus_priv.use_count < 0); ++ ++ if (vuart_bus_priv.use_count != 0) ++ return 0; ++ ++ free_irq(vuart_bus_priv.virq, &vuart_bus_priv); ++ ++ ps3_vuart_irq_destroy(vuart_bus_priv.virq); ++ vuart_bus_priv.virq = NO_IRQ; ++ ++ kfree(vuart_bus_priv.bmp); ++ vuart_bus_priv.bmp = NULL; ++ ++ pr_debug(" <- %s:%d\n", __func__, __LINE__); ++ return 0; + } + +-static int ps3_vuart_probe(struct device *_dev) ++static int ps3_vuart_probe(struct ps3_system_bus_device *dev) + { + int result; +- unsigned int port_number; +- struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); +- struct ps3_vuart_port_driver *drv = +- to_ps3_vuart_port_driver(_dev->driver); ++ struct ps3_vuart_port_driver *drv; ++ struct ps3_vuart_port_priv *priv = NULL; + + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); + ++ drv = ps3_system_bus_dev_to_vuart_drv(dev); ++ ++ dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__, ++ drv->core.core.name); ++ + BUG_ON(!drv); + +- down(&vuart_bus_priv.probe_mutex); ++ if(dev->port_number >= PORT_COUNT) { ++ BUG(); ++ return -EINVAL; ++ } + +- /* Setup vuart_bus_priv.devices[]. */ ++ down(&vuart_bus_priv.probe_mutex); + +- result = ps3_vuart_match_id_to_port(dev->match_id, +- &port_number); ++ result = ps3_vuart_bus_interrupt_get(); + +- if (result) { +- dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", +- __func__, __LINE__, dev->match_id); +- result = -EINVAL; +- goto fail_match; +- } ++ if (result) ++ goto fail_setup_interrupt; + +- if (vuart_bus_priv.devices[port_number]) { ++ if (vuart_bus_priv.devices[dev->port_number]) { + dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, +- __LINE__, port_number); ++ __LINE__, dev->port_number); + result = -EBUSY; +- goto fail_match; ++ goto fail_busy; + } + +- vuart_bus_priv.devices[port_number] = dev; ++ vuart_bus_priv.devices[dev->port_number] = dev; + +- /* Setup dev->priv. */ ++ /* Setup dev->driver_priv. */ + +- dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL); ++ dev->driver_priv = kzalloc(sizeof(struct ps3_vuart_port_priv), ++ GFP_KERNEL); + +- if (!dev->priv) { ++ if (!dev->driver_priv) { + result = -ENOMEM; +- goto fail_alloc; ++ goto fail_dev_malloc; + } + +- dev->priv->port_number = port_number; +- +- INIT_LIST_HEAD(&dev->priv->tx_list.head); +- spin_lock_init(&dev->priv->tx_list.lock); ++ priv = to_port_priv(dev); + +- INIT_LIST_HEAD(&dev->priv->rx_list.head); +- spin_lock_init(&dev->priv->rx_list.lock); ++ INIT_LIST_HEAD(&priv->tx_list.head); ++ spin_lock_init(&priv->tx_list.lock); + +- INIT_WORK(&dev->priv->work.work, NULL); +- spin_lock_init(&dev->priv->work.lock); +- dev->priv->work.trigger = 0; +- dev->priv->work.dev = dev; ++ INIT_LIST_HEAD(&priv->rx_list.head); ++ spin_lock_init(&priv->rx_list.lock); + +- if (++vuart_bus_priv.use_count == 1) { +- +- result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, +- (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq); +- +- if (result) { +- dev_dbg(&dev->core, +- "%s:%d: ps3_vuart_irq_setup failed (%d)\n", +- __func__, __LINE__, result); +- result = -EPERM; +- goto fail_alloc_irq; +- } +- +- result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, +- IRQF_DISABLED, "vuart", &vuart_bus_priv); +- +- if (result) { +- dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n", +- __func__, __LINE__, result); +- goto fail_request_irq; +- } +- } ++ INIT_WORK(&priv->rx_list.work.work, NULL); ++ priv->rx_list.work.trigger = 0; ++ priv->rx_list.work.dev = dev; + + /* clear stale pending interrupts */ + +@@ -936,150 +1084,158 @@ static int ps3_vuart_probe(struct device + + fail_probe: + ps3_vuart_set_interrupt_mask(dev, 0); +-fail_request_irq: +- ps3_vuart_irq_destroy(vuart_bus_priv.virq); +- vuart_bus_priv.virq = NO_IRQ; +-fail_alloc_irq: +- --vuart_bus_priv.use_count; +- kfree(dev->priv); +- dev->priv = NULL; +-fail_alloc: +- vuart_bus_priv.devices[port_number] = NULL; +-fail_match: ++ kfree(dev->driver_priv); ++ dev->driver_priv = NULL; ++fail_dev_malloc: ++ vuart_bus_priv.devices[dev->port_number] = NULL; ++fail_busy: ++ ps3_vuart_bus_interrupt_put(); ++fail_setup_interrupt: + up(&vuart_bus_priv.probe_mutex); +- dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); ++ dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__); + return result; + } + +-static int ps3_vuart_remove(struct device *_dev) ++/** ++ * ps3_vuart_cleanup - common cleanup helper. ++ * @dev: The struct ps3_system_bus_device instance. ++ * ++ * Cleans interrupts and HV resources. Must be called with ++ * vuart_bus_priv.probe_mutex held. Used by ps3_vuart_remove and ++ * ps3_vuart_shutdown. After this call, polled reading will still work. ++ */ ++ ++static int ps3_vuart_cleanup(struct ps3_system_bus_device *dev) + { +- struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); +- struct ps3_vuart_port_driver *drv = +- to_ps3_vuart_port_driver(_dev->driver); ++ dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); ++ ++ ps3_vuart_cancel_async(dev); ++ ps3_vuart_set_interrupt_mask(dev, 0); ++ ps3_vuart_bus_interrupt_put(); ++ return 0; ++} ++ ++/** ++ * ps3_vuart_remove - Completely clean the device instance. ++ * @dev: The struct ps3_system_bus_device instance. ++ * ++ * Cleans all memory, interrupts and HV resources. After this call the ++ * device can no longer be used. ++ */ ++ ++static int ps3_vuart_remove(struct ps3_system_bus_device *dev) ++{ ++ struct ps3_vuart_port_priv *priv = to_port_priv(dev); ++ struct ps3_vuart_port_driver *drv; ++ ++ BUG_ON(!dev); + + down(&vuart_bus_priv.probe_mutex); + +- dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, +- dev->core.bus_id); ++ dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, ++ dev->match_id); + +- BUG_ON(vuart_bus_priv.use_count < 1); ++ if(!dev->core.driver) { ++ dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, ++ __LINE__); ++ up(&vuart_bus_priv.probe_mutex); ++ return 0; ++ } + +- if (drv->remove) +- drv->remove(dev); +- else +- dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, +- __LINE__, dev->core.bus_id); ++ drv = ps3_system_bus_dev_to_vuart_drv(dev); + +- vuart_bus_priv.devices[dev->priv->port_number] = NULL; ++ BUG_ON(!drv); + +- if (--vuart_bus_priv.use_count == 0) { ++ if (drv->remove) { ++ drv->remove(dev); ++ } else { ++ dev_dbg(&dev->core, "%s:%d: no remove method\n", __func__, ++ __LINE__); + BUG(); +- free_irq(vuart_bus_priv.virq, &vuart_bus_priv); +- ps3_vuart_irq_destroy(vuart_bus_priv.virq); +- vuart_bus_priv.virq = NO_IRQ; + } + +- kfree(dev->priv); +- dev->priv = NULL; ++ ps3_vuart_cleanup(dev); ++ ++ vuart_bus_priv.devices[dev->port_number] = NULL; ++ kfree(priv); ++ priv = NULL; + ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + up(&vuart_bus_priv.probe_mutex); + return 0; + } + +-static void ps3_vuart_shutdown(struct device *_dev) +-{ +- struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); +- struct ps3_vuart_port_driver *drv = +- to_ps3_vuart_port_driver(_dev->driver); +- +- dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, +- dev->core.bus_id); +- +- if (drv->shutdown) +- drv->shutdown(dev); +- else +- dev_dbg(&dev->core, "%s:%d: %s no shutdown method\n", __func__, +- __LINE__, dev->core.bus_id); +-} +- + /** +- * ps3_vuart_bus - The vuart bus instance. ++ * ps3_vuart_shutdown - Cleans interrupts and HV resources. ++ * @dev: The struct ps3_system_bus_device instance. + * +- * The vuart is managed as a bus that port devices connect to. ++ * Cleans interrupts and HV resources. After this call the ++ * device can still be used in polling mode. This behavior required ++ * by sys-manager to be able to complete the device power operation ++ * sequence. + */ + +-struct bus_type ps3_vuart_bus = { +- .name = "ps3_vuart", +- .match = ps3_vuart_match, +- .probe = ps3_vuart_probe, +- .remove = ps3_vuart_remove, +- .shutdown = ps3_vuart_shutdown, +-}; +- +-int __init ps3_vuart_bus_init(void) ++static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) + { +- int result; ++ struct ps3_vuart_port_driver *drv; + +- pr_debug("%s:%d:\n", __func__, __LINE__); ++ BUG_ON(!dev); + +- if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) +- return -ENODEV; ++ down(&vuart_bus_priv.probe_mutex); + +- init_MUTEX(&vuart_bus_priv.probe_mutex); +- result = bus_register(&ps3_vuart_bus); +- BUG_ON(result); ++ dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, ++ dev->match_id); + +- return result; +-} ++ if(!dev->core.driver) { ++ dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, ++ __LINE__); ++ up(&vuart_bus_priv.probe_mutex); ++ return 0; ++ } + +-void __exit ps3_vuart_bus_exit(void) +-{ +- pr_debug("%s:%d:\n", __func__, __LINE__); +- bus_unregister(&ps3_vuart_bus); +-} ++ drv = ps3_system_bus_dev_to_vuart_drv(dev); + +-core_initcall(ps3_vuart_bus_init); +-module_exit(ps3_vuart_bus_exit); ++ BUG_ON(!drv); + +-/** +- * ps3_vuart_port_release_device - Remove a vuart port device. +- */ ++ if (drv->shutdown) ++ drv->shutdown(dev); ++ else if (drv->remove) { ++ dev_dbg(&dev->core, "%s:%d: no shutdown, calling remove\n", ++ __func__, __LINE__); ++ drv->remove(dev); ++ } else { ++ dev_dbg(&dev->core, "%s:%d: no shutdown method\n", __func__, ++ __LINE__); ++ BUG(); ++ } + +-static void ps3_vuart_port_release_device(struct device *_dev) +-{ +-#if defined(DEBUG) +- struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); ++ ps3_vuart_cleanup(dev); + +- dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); ++ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); + +- BUG_ON(dev->priv && "forgot to free"); +- memset(&dev->core, 0, sizeof(dev->core)); +-#endif ++ up(&vuart_bus_priv.probe_mutex); ++ return 0; + } + +-/** +- * ps3_vuart_port_device_register - Add a vuart port device. +- */ +- +-int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev) ++static int __init ps3_vuart_bus_init(void) + { +- static unsigned int dev_count = 1; +- +- BUG_ON(dev->priv && "forgot to free"); ++ pr_debug("%s:%d:\n", __func__, __LINE__); + +- dev->core.parent = NULL; +- dev->core.bus = &ps3_vuart_bus; +- dev->core.release = ps3_vuart_port_release_device; ++ if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) ++ return -ENODEV; + +- snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", +- dev_count++); ++ init_MUTEX(&vuart_bus_priv.probe_mutex); + +- dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); ++ return 0; ++} + +- return device_register(&dev->core); ++static void __exit ps3_vuart_bus_exit(void) ++{ ++ pr_debug("%s:%d:\n", __func__, __LINE__); + } + +-EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); ++core_initcall(ps3_vuart_bus_init); ++module_exit(ps3_vuart_bus_exit); + + /** + * ps3_vuart_port_driver_register - Add a vuart port device driver. +@@ -1089,12 +1245,18 @@ int ps3_vuart_port_driver_register(struc + { + int result; + +- pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); +- drv->core.bus = &ps3_vuart_bus; +- result = driver_register(&drv->core); ++ pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name); ++ ++ BUG_ON(!drv->core.match_id); ++ BUG_ON(!drv->core.core.name); ++ ++ drv->core.probe = ps3_vuart_probe; ++ drv->core.remove = ps3_vuart_remove; ++ drv->core.shutdown = ps3_vuart_shutdown; ++ ++ result = ps3_system_bus_driver_register(&drv->core); + return result; + } +- + EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register); + + /** +@@ -1103,8 +1265,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_ + + void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) + { +- pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); +- driver_unregister(&drv->core); ++ pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.core.name); ++ ps3_system_bus_driver_unregister(&drv->core); + } +- + EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister); +--- a/drivers/ps3/vuart.h ++++ b/drivers/ps3/vuart.h +@@ -34,29 +34,7 @@ struct ps3_vuart_stats { + struct ps3_vuart_work { + struct work_struct work; + unsigned long trigger; +- spinlock_t lock; +- struct ps3_vuart_port_device* dev; /* to convert work to device */ +-}; +- +-/** +- * struct ps3_vuart_port_priv - private vuart device data. +- */ +- +-struct ps3_vuart_port_priv { +- unsigned int port_number; +- u64 interrupt_mask; +- +- struct { +- spinlock_t lock; +- struct list_head head; +- } tx_list; +- struct { +- unsigned long bytes_held; +- spinlock_t lock; +- struct list_head head; +- } rx_list; +- struct ps3_vuart_stats stats; +- struct ps3_vuart_work work; ++ struct ps3_system_bus_device* dev; /* to convert work to device */ + }; + + /** +@@ -64,32 +42,30 @@ struct ps3_vuart_port_priv { + */ + + struct ps3_vuart_port_driver { +- enum ps3_match_id match_id; +- struct device_driver core; +- int (*probe)(struct ps3_vuart_port_device *); +- int (*remove)(struct ps3_vuart_port_device *); +- void (*shutdown)(struct ps3_vuart_port_device *); +- int (*tx_event)(struct ps3_vuart_port_device *dev); +- int (*rx_event)(struct ps3_vuart_port_device *dev); +- int (*disconnect_event)(struct ps3_vuart_port_device *dev); +- /* int (*suspend)(struct ps3_vuart_port_device *, pm_message_t); */ +- /* int (*resume)(struct ps3_vuart_port_device *); */ ++ struct ps3_system_bus_driver core; ++ int (*probe)(struct ps3_system_bus_device *); ++ int (*remove)(struct ps3_system_bus_device *); ++ void (*shutdown)(struct ps3_system_bus_device *); ++ void (*work)(struct ps3_system_bus_device *); ++ /* int (*tx_event)(struct ps3_system_bus_device *dev); */ ++ /* int (*rx_event)(struct ps3_system_bus_device *dev); */ ++ /* int (*disconnect_event)(struct ps3_system_bus_device *dev); */ ++ /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */ ++ /* int (*resume)(struct ps3_system_bus_device *); */ + }; + + int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv); + void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv); + +-static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver( +- struct device_driver *_drv) +-{ +- return container_of(_drv, struct ps3_vuart_port_driver, core); +-} +-static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device( +- struct device *_dev) ++static inline struct ps3_vuart_port_driver * ++ ps3_system_bus_dev_to_vuart_drv(struct ps3_system_bus_device *_dev) + { +- return container_of(_dev, struct ps3_vuart_port_device, core); ++ struct ps3_system_bus_driver *sbd = ++ ps3_system_bus_dev_to_system_bus_drv(_dev); ++ BUG_ON(!sbd); ++ return container_of(sbd, struct ps3_vuart_port_driver, core); + } +-static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device( ++static inline struct ps3_system_bus_device *ps3_vuart_work_to_system_bus_dev( + struct work_struct *_work) + { + struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work, +@@ -97,14 +73,13 @@ static inline struct ps3_vuart_port_devi + return vw->dev; + } + +-int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, +- unsigned int bytes); +-int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, ++int ps3_vuart_write(struct ps3_system_bus_device *dev, const void* buf, + unsigned int bytes); +-int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func, ++int ps3_vuart_read(struct ps3_system_bus_device *dev, void* buf, + unsigned int bytes); +-void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev); +-void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev, ++int ps3_vuart_read_async(struct ps3_system_bus_device *dev, unsigned int bytes); ++void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev); ++void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev, + unsigned int bytes); + + #endif +--- a/include/asm-powerpc/ps3.h ++++ b/include/asm-powerpc/ps3.h +@@ -408,23 +408,6 @@ static inline void *ps3_system_bus_get_d + + extern struct bus_type ps3_system_bus_type; + +-/* vuart routines */ +- +-struct ps3_vuart_port_priv; +- +-/** +- * struct ps3_vuart_port_device - a device on a vuart port +- */ +- +-struct ps3_vuart_port_device { +- enum ps3_match_id match_id; +- struct device core; +- struct ps3_vuart_port_priv* priv; /* private driver variables */ +- +-}; +- +-int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); +- + /* system manager */ + + #ifdef CONFIG_PS3_SYS_MANAGER --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/52-ps3-legacy-bootloader-hack.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/52-ps3-legacy-bootloader-hack.patch @@ -0,0 +1,23 @@ +A temporary hack to support the legacy 2.6.16 bootloader. This will be +removed as soon as a 2.6.22 bootloader is ready. + +Hacked-by: Geoff Levand +--- + arch/powerpc/kernel/prom.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/powerpc/kernel/prom.c ++++ b/arch/powerpc/kernel/prom.c +@@ -939,6 +939,12 @@ static int __init early_init_dt_scan_mem + size = 0x80000000ul - base; + } + #endif ++#ifdef CONFIG_PPC_PS3 ++ /* temporary hack for the legacy bootloader */ ++ if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "PS3PF")) { ++ size = 0x8000000; ++ } ++#endif + lmb_add(base, size); + } + return 0; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/45-ps3stor_rom.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/45-ps3stor_rom.patch @@ -0,0 +1,864 @@ +Subject: ps3: ROM Storage Driver + +From: Geert Uytterhoeven + +Add a CD/DVD/BD Storage Driver for the PS3: + - Implemented as a SCSI device driver + - Uses software scatter-gather with a 64 KiB bounce buffer as the hypervisor + doesn't support scatter-gather + +Signed-off-by: Geert Uytterhoeven +--- + arch/powerpc/platforms/ps3/Kconfig | 11 + drivers/scsi/Makefile | 1 + drivers/scsi/ps3rom.c | 817 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 829 insertions(+) + +--- a/arch/powerpc/platforms/ps3/Kconfig ++++ b/arch/powerpc/platforms/ps3/Kconfig +@@ -112,4 +112,15 @@ config PS3_DISK + This support is required to access the PS3 hard disk. + In general, all users will say Y or M. + ++config PS3_ROM ++ tristate "PS3 ROM Storage Driver" ++ depends on PPC_PS3 && BLK_DEV_SR ++ select PS3_STORAGE ++ default y ++ help ++ Include support for the PS3 ROM Storage. ++ ++ This support is required to access the PS3 BD/DVD/CD-ROM drive. ++ In general, all users will say Y or M. ++ + endmenu +--- a/drivers/scsi/Makefile ++++ b/drivers/scsi/Makefile +@@ -132,6 +132,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ + obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ + obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o + obj-$(CONFIG_SCSI_STEX) += stex.o ++obj-$(CONFIG_PS3_ROM) += ps3rom.o + + obj-$(CONFIG_ARM) += arm/ + +--- /dev/null ++++ b/drivers/scsi/ps3rom.c +@@ -0,0 +1,817 @@ ++/* ++ * PS3 ROM Storage Driver ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++ ++#define DEVICE_NAME "ps3rom" ++ ++#define BOUNCE_SIZE (64*1024) ++ ++#define PS3ROM_MAX_SECTORS (BOUNCE_SIZE / CD_FRAMESIZE) ++ ++#define LV1_STORAGE_SEND_ATAPI_COMMAND (1) ++ ++ ++struct ps3rom_private { ++ spinlock_t lock; ++ struct task_struct *thread; ++ struct Scsi_Host *host; ++ struct scsi_cmnd *cmd; ++ void (*scsi_done)(struct scsi_cmnd *); ++}; ++#define ps3rom_priv(dev) ((dev)->sbd.core.driver_data) ++ ++struct lv1_atapi_cmnd_block { ++ u8 pkt[32]; /* packet command block */ ++ u32 pktlen; /* should be 12 for ATAPI 8020 */ ++ u32 blocks; ++ u32 block_size; ++ u32 proto; /* transfer mode */ ++ u32 in_out; /* transfer direction */ ++ u64 buffer; /* parameter except command block */ ++ u32 arglen; /* length above */ ++}; ++ ++/* ++ * to position parameter ++ */ ++enum { ++ NOT_AVAIL = -1, ++ USE_SRB_10 = -2, ++ USE_SRB_6 = -3, ++ USE_CDDA_FRAME_RAW = -4 ++}; ++ ++enum lv1_atapi_proto { ++ NA_PROTO = -1, ++ NON_DATA_PROTO = 0, ++ PIO_DATA_IN_PROTO = 1, ++ PIO_DATA_OUT_PROTO = 2, ++ DMA_PROTO = 3 ++}; ++ ++enum lv1_atapi_in_out { ++ DIR_NA = -1, ++ DIR_WRITE = 0, /* memory -> device */ ++ DIR_READ = 1 /* device -> memory */ ++}; ++ ++ ++#ifdef DEBUG ++static const char *scsi_command(unsigned char cmd) ++{ ++ switch (cmd) { ++ case TEST_UNIT_READY: return "TEST_UNIT_READY/GPCMD_TEST_UNIT_READY"; ++ case REZERO_UNIT: return "REZERO_UNIT"; ++ case REQUEST_SENSE: return "REQUEST_SENSE/GPCMD_REQUEST_SENSE"; ++ case FORMAT_UNIT: return "FORMAT_UNIT/GPCMD_FORMAT_UNIT"; ++ case READ_BLOCK_LIMITS: return "READ_BLOCK_LIMITS"; ++ case REASSIGN_BLOCKS: return "REASSIGN_BLOCKS/INITIALIZE_ELEMENT_STATUS"; ++ case READ_6: return "READ_6"; ++ case WRITE_6: return "WRITE_6/MI_REPORT_TARGET_PGS"; ++ case SEEK_6: return "SEEK_6"; ++ case READ_REVERSE: return "READ_REVERSE"; ++ case WRITE_FILEMARKS: return "WRITE_FILEMARKS/SAI_READ_CAPACITY_16"; ++ case SPACE: return "SPACE"; ++ case INQUIRY: return "INQUIRY/GPCMD_INQUIRY"; ++ case RECOVER_BUFFERED_DATA: return "RECOVER_BUFFERED_DATA"; ++ case MODE_SELECT: return "MODE_SELECT"; ++ case RESERVE: return "RESERVE"; ++ case RELEASE: return "RELEASE"; ++ case COPY: return "COPY"; ++ case ERASE: return "ERASE"; ++ case MODE_SENSE: return "MODE_SENSE"; ++ case START_STOP: return "START_STOP/GPCMD_START_STOP_UNIT"; ++ case RECEIVE_DIAGNOSTIC: return "RECEIVE_DIAGNOSTIC"; ++ case SEND_DIAGNOSTIC: return "SEND_DIAGNOSTIC"; ++ case ALLOW_MEDIUM_REMOVAL: return "ALLOW_MEDIUM_REMOVAL/GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL"; ++ case SET_WINDOW: return "SET_WINDOW"; ++ case READ_CAPACITY: return "READ_CAPACITY/GPCMD_READ_CDVD_CAPACITY"; ++ case READ_10: return "READ_10/GPCMD_READ_10"; ++ case WRITE_10: return "WRITE_10/GPCMD_WRITE_10"; ++ case SEEK_10: return "SEEK_10/POSITION_TO_ELEMENT/GPCMD_SEEK"; ++ case WRITE_VERIFY: return "WRITE_VERIFY/GPCMD_WRITE_AND_VERIFY_10"; ++ case VERIFY: return "VERIFY/GPCMD_VERIFY_10"; ++ case SEARCH_HIGH: return "SEARCH_HIGH"; ++ case SEARCH_EQUAL: return "SEARCH_EQUAL"; ++ case SEARCH_LOW: return "SEARCH_LOW"; ++ case SET_LIMITS: return "SET_LIMITS"; ++ case PRE_FETCH: return "PRE_FETCH/READ_POSITION"; ++ case SYNCHRONIZE_CACHE: return "SYNCHRONIZE_CACHE/GPCMD_FLUSH_CACHE"; ++ case LOCK_UNLOCK_CACHE: return "LOCK_UNLOCK_CACHE"; ++ case READ_DEFECT_DATA: return "READ_DEFECT_DATA"; ++ case MEDIUM_SCAN: return "MEDIUM_SCAN"; ++ case COMPARE: return "COMPARE"; ++ case COPY_VERIFY: return "COPY_VERIFY"; ++ case WRITE_BUFFER: return "WRITE_BUFFER"; ++ case READ_BUFFER: return "READ_BUFFER"; ++ case UPDATE_BLOCK: return "UPDATE_BLOCK"; ++ case READ_LONG: return "READ_LONG"; ++ case WRITE_LONG: return "WRITE_LONG"; ++ case CHANGE_DEFINITION: return "CHANGE_DEFINITION"; ++ case WRITE_SAME: return "WRITE_SAME"; ++ case READ_TOC: return "READ_TOC/GPCMD_READ_TOC_PMA_ATIP"; ++ case LOG_SELECT: return "LOG_SELECT"; ++ case LOG_SENSE: return "LOG_SENSE"; ++ case MODE_SELECT_10: return "MODE_SELECT_10/GPCMD_MODE_SELECT_10"; ++ case RESERVE_10: return "RESERVE_10"; ++ case RELEASE_10: return "RELEASE_10"; ++ case MODE_SENSE_10: return "MODE_SENSE_10/GPCMD_MODE_SENSE_10"; ++ case PERSISTENT_RESERVE_IN: return "PERSISTENT_RESERVE_IN"; ++ case PERSISTENT_RESERVE_OUT: return "PERSISTENT_RESERVE_OUT"; ++ case REPORT_LUNS: return "REPORT_LUNS"; ++ case MAINTENANCE_IN: return "MAINTENANCE_IN/GPCMD_SEND_KEY"; ++ case MOVE_MEDIUM: return "MOVE_MEDIUM"; ++ case EXCHANGE_MEDIUM: return "EXCHANGE_MEDIUM/GPCMD_LOAD_UNLOAD"; ++ case READ_12: return "READ_12/GPCMD_READ_12"; ++ case WRITE_12: return "WRITE_12"; ++ case WRITE_VERIFY_12: return "WRITE_VERIFY_12"; ++ case SEARCH_HIGH_12: return "SEARCH_HIGH_12"; ++ case SEARCH_EQUAL_12: return "SEARCH_EQUAL_12"; ++ case SEARCH_LOW_12: return "SEARCH_LOW_12"; ++ case READ_ELEMENT_STATUS: return "READ_ELEMENT_STATUS"; ++ case SEND_VOLUME_TAG: return "SEND_VOLUME_TAG/GPCMD_SET_STREAMING"; ++ case WRITE_LONG_2: return "WRITE_LONG_2"; ++ case READ_16: return "READ_16"; ++ case WRITE_16: return "WRITE_16"; ++ case VERIFY_16: return "VERIFY_16"; ++ case SERVICE_ACTION_IN: return "SERVICE_ACTION_IN"; ++ case ATA_16: return "ATA_16"; ++ case ATA_12: return "ATA_12/GPCMD_BLANK"; ++ case GPCMD_CLOSE_TRACK: return "GPCMD_CLOSE_TRACK"; ++ case GPCMD_GET_CONFIGURATION: return "GPCMD_GET_CONFIGURATION"; ++ case GPCMD_GET_EVENT_STATUS_NOTIFICATION: return "GPCMD_GET_EVENT_STATUS_NOTIFICATION"; ++ case GPCMD_GET_PERFORMANCE: return "GPCMD_GET_PERFORMANCE"; ++ case GPCMD_MECHANISM_STATUS: return "GPCMD_MECHANISM_STATUS"; ++ case GPCMD_PAUSE_RESUME: return "GPCMD_PAUSE_RESUME"; ++ case GPCMD_PLAY_AUDIO_10: return "GPCMD_PLAY_AUDIO_10"; ++ case GPCMD_PLAY_AUDIO_MSF: return "GPCMD_PLAY_AUDIO_MSF"; ++ case GPCMD_PLAY_AUDIO_TI: return "GPCMD_PLAY_AUDIO_TI/GPCMD_PLAYAUDIO_TI"; ++ case GPCMD_PLAY_CD: return "GPCMD_PLAY_CD"; ++ case GPCMD_READ_BUFFER_CAPACITY: return "GPCMD_READ_BUFFER_CAPACITY"; ++ case GPCMD_READ_CD: return "GPCMD_READ_CD"; ++ case GPCMD_READ_CD_MSF: return "GPCMD_READ_CD_MSF"; ++ case GPCMD_READ_DISC_INFO: return "GPCMD_READ_DISC_INFO"; ++ case GPCMD_READ_DVD_STRUCTURE: return "GPCMD_READ_DVD_STRUCTURE"; ++ case GPCMD_READ_FORMAT_CAPACITIES: return "GPCMD_READ_FORMAT_CAPACITIES"; ++ case GPCMD_READ_HEADER: return "GPCMD_READ_HEADER"; ++ case GPCMD_READ_TRACK_RZONE_INFO: return "GPCMD_READ_TRACK_RZONE_INFO"; ++ case GPCMD_READ_SUBCHANNEL: return "GPCMD_READ_SUBCHANNEL"; ++ case GPCMD_REPAIR_RZONE_TRACK: return "GPCMD_REPAIR_RZONE_TRACK"; ++ case GPCMD_REPORT_KEY: return "GPCMD_REPORT_KEY"; ++ case GPCMD_RESERVE_RZONE_TRACK: return "GPCMD_RESERVE_RZONE_TRACK"; ++ case GPCMD_SEND_CUE_SHEET: return "GPCMD_SEND_CUE_SHEET"; ++ case GPCMD_SCAN: return "GPCMD_SCAN"; ++ case GPCMD_SEND_DVD_STRUCTURE: return "GPCMD_SEND_DVD_STRUCTURE"; ++ case GPCMD_SEND_EVENT: return "GPCMD_SEND_EVENT"; ++ case GPCMD_SEND_OPC: return "GPCMD_SEND_OPC"; ++ case GPCMD_SET_READ_AHEAD: return "GPCMD_SET_READ_AHEAD"; ++ case GPCMD_STOP_PLAY_SCAN: return "GPCMD_STOP_PLAY_SCAN"; ++ case GPCMD_SET_SPEED: return "GPCMD_SET_SPEED"; ++ case GPCMD_GET_MEDIA_STATUS: return "GPCMD_GET_MEDIA_STATUS"; ++ ++ default: ++ return "***UNKNOWN***"; ++ } ++} ++#else /* !DEBUG */ ++static inline const char *scsi_command(unsigned char cmd) { return NULL; } ++#endif /* DEBUG */ ++ ++ ++static int ps3rom_slave_alloc(struct scsi_device *scsi_dev) ++{ ++ struct ps3_storage_device *dev; ++ ++ dev = (struct ps3_storage_device *)scsi_dev->host->hostdata[0]; ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %u, channel %u\n", __func__, ++ __LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel); ++ ++ scsi_dev->hostdata = dev; ++ return 0; ++} ++ ++static int ps3rom_slave_configure(struct scsi_device *scsi_dev) ++{ ++ struct ps3_storage_device *dev = scsi_dev->hostdata; ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %u, channel %u\n", __func__, ++ __LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel); ++ ++ /* ++ * ATAPI SFF8020 devices use MODE_SENSE_10, ++ * so we can prohibit MODE_SENSE_6 ++ */ ++ scsi_dev->use_10_for_ms = 1; ++ ++ return 0; ++} ++ ++static void ps3rom_slave_destroy(struct scsi_device *scsi_dev) ++{ ++} ++ ++static int ps3rom_queuecommand(struct scsi_cmnd *cmd, ++ void (*done)(struct scsi_cmnd *)) ++{ ++ struct ps3_storage_device *dev = cmd->device->hostdata; ++ struct ps3rom_private *priv = ps3rom_priv(dev); ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%02x (%s)\n", __func__, ++ __LINE__, cmd->cmnd[0], scsi_command(cmd->cmnd[0])); ++ ++ spin_lock_irq(&priv->lock); ++ if (priv->cmd) { ++ /* no more than one can be processed */ ++ dev_err(&dev->sbd.core, "%s:%u: more than 1 command queued\n", ++ __func__, __LINE__); ++ spin_unlock_irq(&priv->lock); ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } ++ ++ // FIXME Prevalidate commands? ++ priv->cmd = cmd; ++ priv->scsi_done = done; ++ spin_unlock_irq(&priv->lock); ++ wake_up_process(priv->thread); ++ return 0; ++} ++ ++/* ++ * copy data from device into scatter/gather buffer ++ */ ++static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf, ++ int buflen) ++{ ++ int k, req_len, act_len, len, active; ++ void *kaddr; ++ struct scatterlist *sgpnt; ++ ++ if (!cmd->request_bufflen) ++ return 0; ++ ++ if (!cmd->request_buffer) ++ return DID_ERROR << 16; ++ ++ if (cmd->sc_data_direction != DMA_BIDIRECTIONAL && ++ cmd->sc_data_direction != DMA_FROM_DEVICE) ++ return DID_ERROR << 16; ++ ++ if (!cmd->use_sg) { ++ req_len = cmd->request_bufflen; ++ act_len = min(req_len, buflen); ++ memcpy(cmd->request_buffer, buf, act_len); ++ cmd->resid = req_len - act_len; ++ return 0; ++ } ++ ++ sgpnt = cmd->request_buffer; ++ active = 1; ++ for (k = 0, req_len = 0, act_len = 0; k < cmd->use_sg; ++k, ++sgpnt) { ++ if (active) { ++ kaddr = kmap_atomic(sgpnt->page, KM_USER0); ++ if (!kaddr) ++ return DID_ERROR << 16; ++ len = sgpnt->length; ++ if ((req_len + len) > buflen) { ++ active = 0; ++ len = buflen - req_len; ++ } ++ memcpy(kaddr + sgpnt->offset, buf + req_len, len); ++ kunmap_atomic(kaddr, KM_USER0); ++ act_len += len; ++ } ++ req_len += sgpnt->length; ++ } ++ cmd->resid = req_len - act_len; ++ return 0; ++} ++ ++/* ++ * copy data from scatter/gather into device's buffer ++ */ ++static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf, int buflen) ++{ ++ int k, req_len, len, fin; ++ void *kaddr; ++ struct scatterlist *sgpnt; ++ ++ if (!cmd->request_bufflen) ++ return 0; ++ ++ if (!cmd->request_buffer) ++ return -1; ++ ++ if (cmd->sc_data_direction != DMA_BIDIRECTIONAL && ++ cmd->sc_data_direction != DMA_TO_DEVICE) ++ return -1; ++ ++ if (!cmd->use_sg) { ++ req_len = cmd->request_bufflen; ++ len = min(req_len, buflen); ++ memcpy(buf, cmd->request_buffer, len); ++ return len; ++ } ++ ++ sgpnt = cmd->request_buffer; ++ for (k = 0, req_len = 0, fin = 0; k < cmd->use_sg; ++k, ++sgpnt) { ++ kaddr = kmap_atomic(sgpnt->page, KM_USER0); ++ if (!kaddr) ++ return -1; ++ len = sgpnt->length; ++ if ((req_len + len) > buflen) { ++ len = buflen - req_len; ++ fin = 1; ++ } ++ memcpy(buf + req_len, kaddr + sgpnt->offset, len); ++ kunmap_atomic(kaddr, KM_USER0); ++ if (fin) ++ return req_len + len; ++ req_len += sgpnt->length; ++ } ++ return req_len; ++} ++ ++static int decode_lv1_status(u64 status, unsigned char *sense_key, ++ unsigned char *asc, unsigned char *ascq) ++{ ++ if (((status >> 24) & 0xff) != SAM_STAT_CHECK_CONDITION) ++ return -1; ++ ++ *sense_key = (status >> 16) & 0xff; ++ *asc = (status >> 8) & 0xff; ++ *ascq = status & 0xff; ++ return 0; ++} ++ ++static inline unsigned int srb6_lba(const struct scsi_cmnd *cmd) ++{ ++ BUG_ON(cmd->cmnd[1] & 0xe0); // FIXME lun == 0 ++ return cmd->cmnd[1] << 16 | cmd->cmnd[2] << 8 | cmd->cmnd[3]; ++} ++ ++static inline unsigned int srb6_len(const struct scsi_cmnd *cmd) ++{ ++ return cmd->cmnd[4]; ++} ++ ++static inline unsigned int srb10_lba(const struct scsi_cmnd *cmd) ++{ ++ return cmd->cmnd[2] << 24 | cmd->cmnd[3] << 16 | cmd->cmnd[4] << 8 | ++ cmd->cmnd[5]; ++} ++ ++static inline unsigned int srb10_len(const struct scsi_cmnd *cmd) ++{ ++ return cmd->cmnd[7] << 8 | cmd->cmnd[8]; ++} ++ ++static inline unsigned int cdda_raw_len(const struct scsi_cmnd *cmd) ++{ ++ unsigned int nframes; ++ ++ nframes = cmd->cmnd[6] << 16 | cmd->cmnd[7] << 8 | cmd->cmnd[8]; ++ return nframes * CD_FRAMESIZE_RAW; ++} ++ ++static u64 ps3rom_send_atapi_command(struct ps3_storage_device *dev, ++ struct lv1_atapi_cmnd_block *cmd) ++{ ++ dev_dbg(&dev->sbd.core, "%s:%u: send ATAPI command 0x%02x (%s)\n", ++ __func__, __LINE__, cmd->pkt[0], scsi_command(cmd->pkt[0])); ++ ++ return ps3stor_send_command(dev, LV1_STORAGE_SEND_ATAPI_COMMAND, ++ ps3_mm_phys_to_lpar(__pa(cmd)), ++ sizeof(*cmd), cmd->buffer, cmd->arglen); ++} ++ ++static void ps3rom_atapi_request(struct ps3_storage_device *dev, ++ struct scsi_cmnd *cmd, unsigned int len, ++ int proto, int in_out, int auto_sense) ++{ ++ struct lv1_atapi_cmnd_block atapi_cmnd; ++ unsigned char *cmnd = cmd->cmnd; ++ u64 status; ++ unsigned char sense_key, asc, ascq; ++ ++ if (len > dev->bounce_size) { ++ static int printed; ++ if (!printed++) ++ dev_err(&dev->sbd.core, ++ "%s:%u: data size too large %u > %lu\n", ++ __func__, __LINE__, len, dev->bounce_size); ++ cmd->result = DID_ERROR << 16; ++ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); ++ cmd->sense_buffer[0] = 0x70; ++ cmd->sense_buffer[2] = ILLEGAL_REQUEST; ++ return; ++ } ++ ++ memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block)); ++ memcpy(&atapi_cmnd.pkt, cmnd, 12); ++ atapi_cmnd.pktlen = 12; ++ atapi_cmnd.proto = proto; ++ if (in_out != DIR_NA) ++ atapi_cmnd.in_out = in_out; ++ ++ if (atapi_cmnd.in_out == DIR_WRITE) { ++ // FIXME check error ++ fetch_to_dev_buffer(cmd, dev->bounce_buf, len); ++ } ++ ++ atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */ ++ ++ atapi_cmnd.blocks = atapi_cmnd.arglen = len; ++ atapi_cmnd.buffer = dev->bounce_lpar; ++ ++ status = ps3rom_send_atapi_command(dev, &atapi_cmnd); ++ if (status == -1) { ++ cmd->result = DID_ERROR << 16; /* FIXME: is better other error code ? */ ++ return; ++ } ++ ++ if (!status) { ++ /* OK, completed */ ++ if (atapi_cmnd.in_out == DIR_READ) { ++ // FIXME check error ++ fill_from_dev_buffer(cmd, dev->bounce_buf, len); ++ } ++ cmd->result = DID_OK << 16; ++ return; ++ } ++ ++ /* error */ ++ if (!auto_sense) { ++ cmd->result = (DID_ERROR << 16) | (CHECK_CONDITION << 1); ++ dev_err(&dev->sbd.core, "%s:%u: end error without autosense\n", ++ __func__, __LINE__); ++ return; ++ } ++ ++ if (!decode_lv1_status(status, &sense_key, &asc, &ascq)) { ++ /* lv1 may have issued autosense ... */ ++ cmd->sense_buffer[0] = 0x70; ++ cmd->sense_buffer[2] = sense_key; ++ cmd->sense_buffer[7] = 16 - 6; ++ cmd->sense_buffer[12] = asc; ++ cmd->sense_buffer[13] = ascq; ++ cmd->result = SAM_STAT_CHECK_CONDITION; ++ return; ++ } ++ ++ /* do auto sense by ourselves */ ++ memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block)); ++ atapi_cmnd.pkt[0] = REQUEST_SENSE; ++ atapi_cmnd.pkt[4] = 18; ++ atapi_cmnd.pktlen = 12; ++ atapi_cmnd.arglen = atapi_cmnd.blocks = atapi_cmnd.pkt[4]; ++ atapi_cmnd.block_size = 1; ++ atapi_cmnd.proto = DMA_PROTO; ++ atapi_cmnd.in_out = DIR_READ; ++ atapi_cmnd.buffer = dev->bounce_lpar; ++ ++ /* issue REQUEST_SENSE command */ ++ status = ps3rom_send_atapi_command(dev, &atapi_cmnd); ++ if (status == -1) { ++ cmd->result = DID_ERROR << 16; /* FIXME: is better other error code ? */ ++ return; ++ } ++ ++ /* scsi spec says request sense should never get error */ ++ if (status) { ++ decode_lv1_status(status, &sense_key, &asc, &ascq); ++ dev_err(&dev->sbd.core, ++ "%s:%u: auto REQUEST_SENSE error %#x %#x %#x\n", ++ __func__, __LINE__, sense_key, asc, ascq); ++ } ++ ++ memcpy(cmd->sense_buffer, dev->bounce_buf, ++ min_t(size_t, atapi_cmnd.pkt[4], SCSI_SENSE_BUFFERSIZE)); ++ cmd->result = SAM_STAT_CHECK_CONDITION; ++} ++ ++static void ps3rom_read_request(struct ps3_storage_device *dev, ++ struct scsi_cmnd *cmd, u32 start_sector, ++ u32 sectors) ++{ ++ u64 status; ++ ++ status = ps3stor_read_write_sectors(dev, dev->bounce_lpar, ++ start_sector, sectors, 0); ++ if (status == -1) { ++ cmd->result = DID_ERROR << 16; /* FIXME: other error code? */ ++ return; ++ } ++ ++ if (status) { ++ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); ++ decode_lv1_status(dev->lv1_status, &cmd->sense_buffer[2], ++ &cmd->sense_buffer[12], ++ &cmd->sense_buffer[13]); ++ cmd->sense_buffer[7] = 16 - 6; // FIXME hardcoded numbers? ++ cmd->result = SAM_STAT_CHECK_CONDITION; ++ return; ++ } ++ ++ // FIXME check error ++ fill_from_dev_buffer(cmd, dev->bounce_buf, sectors * CD_FRAMESIZE); ++ ++ cmd->result = DID_OK << 16; ++} ++ ++static void ps3rom_write_request(struct ps3_storage_device *dev, ++ struct scsi_cmnd *cmd, u32 start_sector, ++ u32 sectors) ++{ ++ u64 status; ++ ++ // FIXME check error ++ fetch_to_dev_buffer(cmd, dev->bounce_buf, sectors * CD_FRAMESIZE); ++ ++ status = ps3stor_read_write_sectors(dev, dev->bounce_lpar, ++ start_sector, sectors, 1); ++ if (status == -1) { ++ cmd->result = DID_ERROR << 16; /* FIXME: other error code? */ ++ return; ++ } ++ ++ if (status) { ++ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); ++ decode_lv1_status(dev->lv1_status, &cmd->sense_buffer[2], ++ &cmd->sense_buffer[12], ++ &cmd->sense_buffer[13]); ++ cmd->sense_buffer[7] = 16 - 6; // FIXME hardcoded numbers? ++ cmd->result = SAM_STAT_CHECK_CONDITION; ++ return; ++ } ++ ++ cmd->result = DID_OK << 16; ++} ++ ++static void ps3rom_request(struct ps3_storage_device *dev, ++ struct scsi_cmnd *cmd) ++{ ++ unsigned char opcode = cmd->cmnd[0]; ++ struct ps3rom_private *priv = ps3rom_priv(dev); ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%02x (%s)\n", __func__, ++ __LINE__, opcode, scsi_command(opcode)); ++ ++ switch (opcode) { ++ case INQUIRY: ++ ps3rom_atapi_request(dev, cmd, srb6_len(cmd), ++ PIO_DATA_IN_PROTO, DIR_READ, 1); ++ break; ++ ++ case REQUEST_SENSE: ++ ps3rom_atapi_request(dev, cmd, srb6_len(cmd), ++ PIO_DATA_IN_PROTO, DIR_READ, 0); ++ break; ++ ++ case ALLOW_MEDIUM_REMOVAL: ++ case START_STOP: ++ case TEST_UNIT_READY: ++ ps3rom_atapi_request(dev, cmd, 0, NON_DATA_PROTO, DIR_NA, 1); ++ break; ++ ++ case READ_CAPACITY: ++ ps3rom_atapi_request(dev, cmd, 8, PIO_DATA_IN_PROTO, DIR_READ, ++ 1); ++ break; ++ ++ case MODE_SENSE_10: ++ case READ_TOC: ++ case GPCMD_GET_CONFIGURATION: ++ case GPCMD_READ_DISC_INFO: ++ ps3rom_atapi_request(dev, cmd, srb10_len(cmd), ++ PIO_DATA_IN_PROTO, DIR_READ, 1); ++ break; ++ ++ case READ_6: ++ ps3rom_read_request(dev, cmd, srb6_lba(cmd), srb6_len(cmd)); ++ break; ++ ++ case READ_10: ++ ps3rom_read_request(dev, cmd, srb10_lba(cmd), srb10_len(cmd)); ++ break; ++ ++ case WRITE_6: ++ ps3rom_write_request(dev, cmd, srb6_lba(cmd), srb6_len(cmd)); ++ break; ++ ++ case WRITE_10: ++ ps3rom_write_request(dev, cmd, srb10_lba(cmd), srb10_len(cmd)); ++ break; ++ ++ case GPCMD_READ_CD: ++ ps3rom_atapi_request(dev, cmd, cdda_raw_len(cmd), DMA_PROTO, ++ DIR_READ, 1); ++ break; ++ ++ default: ++ dev_err(&dev->sbd.core, "%s:%u: illegal request 0x%02x (%s)\n", ++ __func__, __LINE__, opcode, scsi_command(opcode)); ++ cmd->result = DID_ERROR << 16; ++ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); ++ cmd->sense_buffer[0] = 0x70; ++ cmd->sense_buffer[2] = ILLEGAL_REQUEST; ++ } ++ ++ spin_lock_irq(&priv->lock); ++ priv->cmd = NULL; ++ priv->scsi_done(cmd); ++ spin_unlock_irq(&priv->lock); ++} ++ ++static int ps3rom_thread(void *data) ++{ ++ struct ps3_storage_device *dev = data; ++ struct ps3rom_private *priv = ps3rom_priv(dev); ++ struct scsi_cmnd *cmd; ++ ++ dev_dbg(&dev->sbd.core, "%s thread init\n", __func__); ++ ++ current->flags |= PF_NOFREEZE; ++ ++ while (!kthread_should_stop()) { ++ spin_lock_irq(&priv->lock); ++ set_current_state(TASK_INTERRUPTIBLE); ++ cmd = priv->cmd; ++ spin_unlock_irq(&priv->lock); ++ if (!cmd) { ++ schedule(); ++ continue; ++ } ++ ps3rom_request(dev, cmd); ++ } ++ ++ dev_dbg(&dev->sbd.core, "%s thread exit\n", __func__); ++ return 0; ++} ++ ++ ++static struct scsi_host_template ps3rom_host_template = { ++ .name = DEVICE_NAME, ++ .slave_alloc = ps3rom_slave_alloc, ++ .slave_configure = ps3rom_slave_configure, ++ .slave_destroy = ps3rom_slave_destroy, ++ .queuecommand = ps3rom_queuecommand, ++ .can_queue = 1, ++ .this_id = 7, ++ .sg_tablesize = SG_ALL, ++ .cmd_per_lun = 1, ++ .emulated = 1, /* only sg driver uses this */ ++ .max_sectors = PS3ROM_MAX_SECTORS, ++ .use_clustering = ENABLE_CLUSTERING, ++ .module = THIS_MODULE, ++}; ++ ++ ++static int __devinit ps3rom_probe(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ struct ps3rom_private *priv; ++ int error; ++ struct Scsi_Host *host; ++ struct task_struct *task; ++ ++ if (dev->blk_size != CD_FRAMESIZE) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: cannot handle block size %lu\n", __func__, ++ __LINE__, dev->blk_size); ++ return -EINVAL; ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ ps3rom_priv(dev) = priv; ++ spin_lock_init(&priv->lock); ++ ++ dev->bounce_size = BOUNCE_SIZE; ++ dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA); ++ if (!dev->bounce_buf) { ++ error = -ENOMEM; ++ goto fail_free_priv; ++ } ++ ++ error = ps3stor_setup(dev, DEVICE_NAME); ++ if (error) ++ goto fail_free_bounce; ++ ++ host = scsi_host_alloc(&ps3rom_host_template, ++ sizeof(struct ps3_system_bus_device *)); ++ if (!host) { ++ dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed\n", ++ __func__, __LINE__); ++ goto fail_teardown; ++ } ++ ++ priv->host = host; ++ host->hostdata[0] = (unsigned long)dev; ++ ++ /* One device/LUN per SCSI bus */ ++ host->max_id = 1; ++ host->max_lun = 1; ++ ++ error = scsi_add_host(host, &dev->sbd.core); ++ if (error) { ++ dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed %d\n", ++ __func__, __LINE__, error); ++ error = -ENODEV; ++ goto fail_host_put; ++ } ++ ++ task = kthread_run(ps3rom_thread, dev, DEVICE_NAME); ++ if (IS_ERR(task)) { ++ error = PTR_ERR(task); ++ goto fail_remove_host; ++ } ++ priv->thread = task; ++ ++ scsi_scan_host(host); ++ return 0; ++ ++fail_remove_host: ++ scsi_remove_host(host); ++fail_host_put: ++ scsi_host_put(host); ++fail_teardown: ++ ps3stor_teardown(dev); ++fail_free_bounce: ++ kfree(dev->bounce_buf); ++fail_free_priv: ++ kfree(priv); ++ return error; ++} ++ ++static int ps3rom_remove(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ struct ps3rom_private *priv = ps3rom_priv(dev); ++ ++ scsi_remove_host(priv->host); ++ scsi_host_put(priv->host); ++ kthread_stop(priv->thread); ++ ps3stor_teardown(dev); ++ kfree(dev->bounce_buf); ++ kfree(priv); ++ return 0; ++} ++ ++ ++static struct ps3_system_bus_driver ps3rom = { ++ .match_id = PS3_MATCH_ID_STOR_ROM, ++ .core.name = DEVICE_NAME, ++ .core.owner = THIS_MODULE, ++ .probe = ps3rom_probe, ++ .remove = ps3rom_remove ++}; ++ ++ ++static int __init ps3rom_init(void) ++{ ++ return ps3_system_bus_driver_register(&ps3rom); ++} ++ ++static void __exit ps3rom_exit(void) ++{ ++ ps3_system_bus_driver_unregister(&ps3rom); ++} ++ ++module_init(ps3rom_init); ++module_exit(ps3rom_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("PS3 ROM Storage Driver"); ++MODULE_AUTHOR("Sony Corporation"); ++MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_ROM); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/25-powerpc-localize-mmu-off.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/25-powerpc-localize-mmu-off.patch @@ -0,0 +1,27 @@ +Subject: powerpc: Localize mmu_off + +This just removes the dependency __mmu_off has on the symbol +__after_prom_start. I found the current code inconvenient when I +wanted to put some debugging code between the call to __mmu_off +and the branch to __after_prom_start. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/kernel/head_64.S | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/head_64.S ++++ b/arch/powerpc/kernel/head_64.S +@@ -1695,9 +1695,11 @@ _GLOBAL(__start_initialization_multiplat + 2: + + /* Switch off MMU if not already */ +- LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) ++ LOAD_REG_IMMEDIATE(r4, __mmu_off_return - KERNELBASE) + add r4,r4,r30 + bl .__mmu_off ++__mmu_off_return: ++ + b .__after_prom_start + + _STATIC(__boot_from_prom) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/16-ps3-usb-fix-return.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/16-ps3-usb-fix-return.patch @@ -0,0 +1,33 @@ +Subject: PS3: Fix USB return value + +Fix a minor error on the return value of ps3_ehci_driver_register() +and ps3_ohci_driver_register() when running on non-PS3 systems. + +Signed-off-by: Geoff Levand +--- + drivers/usb/host/ehci-ps3.c | 2 +- + drivers/usb/host/ohci-ps3.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/ehci-ps3.c ++++ b/drivers/usb/host/ehci-ps3.c +@@ -227,7 +227,7 @@ static int ps3_ehci_driver_register(stru + { + return firmware_has_feature(FW_FEATURE_PS3_LV1) + ? ps3_system_bus_driver_register(drv) +- : -ENODEV; ++ : 0; + } + + static void ps3_ehci_driver_unregister(struct ps3_system_bus_driver *drv) +--- a/drivers/usb/host/ohci-ps3.c ++++ b/drivers/usb/host/ohci-ps3.c +@@ -230,7 +230,7 @@ static int ps3_ohci_driver_register(stru + { + return firmware_has_feature(FW_FEATURE_PS3_LV1) + ? ps3_system_bus_driver_register(drv) +- : -ENODEV; ++ : 0; + } + + static void ps3_ohci_driver_unregister(struct ps3_system_bus_driver *drv) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/34-Documentation-block-barrier.txt-update.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/34-Documentation-block-barrier.txt-update.patch @@ -0,0 +1,53 @@ +Subject: Update Documentation/block/barrier.txt + +From: Geert Uytterhoeven + +Documentation/block/barrier.txt is not in sync with the actual code: + - blk_queue_ordered() no longer has a gfp_mask parameter + - blk_queue_ordered_locked() no longer exists + - sd_prepare_flush() looks slightly different + +Signed-off-by: Geert Uytterhoeven +--- + Documentation/block/barrier.txt | 16 +++------------- + 1 files changed, 3 insertions(+), 13 deletions(-) + +--- a/Documentation/block/barrier.txt ++++ b/Documentation/block/barrier.txt +@@ -82,23 +82,12 @@ including draining and flushing. + typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq); + + int blk_queue_ordered(request_queue_t *q, unsigned ordered, +- prepare_flush_fn *prepare_flush_fn, +- unsigned gfp_mask); +- +-int blk_queue_ordered_locked(request_queue_t *q, unsigned ordered, +- prepare_flush_fn *prepare_flush_fn, +- unsigned gfp_mask); +- +-The only difference between the two functions is whether or not the +-caller is holding q->queue_lock on entry. The latter expects the +-caller is holding the lock. ++ prepare_flush_fn *prepare_flush_fn); + + @q : the queue in question + @ordered : the ordered mode the driver/device supports + @prepare_flush_fn : this function should prepare @rq such that it + flushes cache to physical medium when executed +-@gfp_mask : gfp_mask used when allocating data structures +- for ordered processing + + For example, SCSI disk driver's prepare_flush_fn looks like the + following. +@@ -106,9 +95,10 @@ following. + static void sd_prepare_flush(request_queue_t *q, struct request *rq) + { + memset(rq->cmd, 0, sizeof(rq->cmd)); +- rq->flags |= REQ_BLOCK_PC; ++ rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->timeout = SD_TIMEOUT; + rq->cmd[0] = SYNCHRONIZE_CACHE; ++ rq->cmd_len = 10; + } + + The following seven ordered modes are supported. The following table --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/09-ps3-inline-DBG.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/09-ps3-inline-DBG.patch @@ -0,0 +1,68 @@ +--- + arch/powerpc/platforms/ps3/htab.c | 3 ++- + arch/powerpc/platforms/ps3/interrupt.c | 3 ++- + arch/powerpc/platforms/ps3/mm.c | 3 ++- + arch/powerpc/platforms/ps3/setup.c | 3 ++- + arch/powerpc/platforms/ps3/smp.c | 3 ++- + 5 files changed, 10 insertions(+), 5 deletions(-) + +--- a/arch/powerpc/platforms/ps3/htab.c ++++ b/arch/powerpc/platforms/ps3/htab.c +@@ -31,7 +31,8 @@ + #if defined(DEBUG) + #define DBG(fmt...) udbg_printf(fmt) + #else +-#define DBG(fmt...) do{if(0)printk(fmt);}while(0) ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} + #endif + + static hpte_t *htab; +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -32,7 +32,8 @@ + #if defined(DEBUG) + #define DBG(fmt...) udbg_printf(fmt) + #else +-#define DBG(fmt...) do{if(0)printk(fmt);}while(0) ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} + #endif + + /** +--- a/arch/powerpc/platforms/ps3/mm.c ++++ b/arch/powerpc/platforms/ps3/mm.c +@@ -32,7 +32,8 @@ + #if defined(DEBUG) + #define DBG(fmt...) udbg_printf(fmt) + #else +-#define DBG(fmt...) do{if(0)printk(fmt);}while(0) ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} + #endif + + enum { +--- a/arch/powerpc/platforms/ps3/setup.c ++++ b/arch/powerpc/platforms/ps3/setup.c +@@ -39,7 +39,8 @@ + #if defined(DEBUG) + #define DBG(fmt...) udbg_printf(fmt) + #else +-#define DBG(fmt...) do{if(0)printk(fmt);}while(0) ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} + #endif + + #if !defined(CONFIG_SMP) +--- a/arch/powerpc/platforms/ps3/smp.c ++++ b/arch/powerpc/platforms/ps3/smp.c +@@ -29,7 +29,8 @@ + #if defined(DEBUG) + #define DBG(fmt...) udbg_printf(fmt) + #else +-#define DBG(fmt...) do{if(0)printk(fmt);}while(0) ++static inline int __attribute__ ((format (printf, 1, 2))) DBG( ++ const char *fmt, ...) {return 0;} + #endif + + static irqreturn_t ipi_function_handler(int irq, void *msg) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/49-spufs-wrap-master-run-bit.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/49-spufs-wrap-master-run-bit.patch @@ -0,0 +1,215 @@ +From: Masato Noguchi + + [ note: This patch is a hot-fix and RFC. ] + +Current kernel uses the master run control bit (MFC_SR1[S]) to +control SPE execution in spufs_run_spu(). PS3 hypervisor does not +permit to change this bit. +This cause Oops that Gerhard pointed out before. + +I know, oldtime kernel used run control register in priv2, and +it was replaced by master run bit to avoid vulnerability. +But, for now, I made a patch closing my eyes to it. +I want to fix it witout using master run bit, if possible. +Does anyone have comments? + + +BTW, in current implementation, if spe was running at disabled +by master run, it seems to be failed at next spu_run syscall. +Is it correct? + + +Signed-off-by: Masato Noguchi +--- + arch/powerpc/platforms/cell/spu_manage.c | 15 +++++++++++++++ + arch/powerpc/platforms/cell/spufs/backing_ops.c | 6 ++++++ + arch/powerpc/platforms/cell/spufs/hw_ops.c | 10 ++++++++++ + arch/powerpc/platforms/cell/spufs/run.c | 4 ++-- + arch/powerpc/platforms/cell/spufs/spufs.h | 1 + + arch/powerpc/platforms/ps3/spu.c | 14 ++++++++++++++ + include/asm-powerpc/spu_priv1.h | 15 +++++++++++++++ + 7 files changed, 63 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/platforms/cell/spu_manage.c ++++ b/arch/powerpc/platforms/cell/spu_manage.c +@@ -35,6 +35,7 @@ + #include + #include + ++#include "spufs/spufs.h" + #include "interrupt.h" + + struct device_node *spu_devnode(struct spu *spu) +@@ -359,8 +360,22 @@ static int of_destroy_spu(struct spu *sp + return 0; + } + ++static int enable_spu_by_master_run(struct spu_context *ctx) ++{ ++ ctx->ops->master_start(ctx); ++ return 0; ++} ++ ++static int disable_spu_by_master_run(struct spu_context *ctx) ++{ ++ ctx->ops->master_stop(ctx); ++ return 0; ++} ++ + const struct spu_management_ops spu_management_of_ops = { + .enumerate_spus = of_enumerate_spus, + .create_spu = of_create_spu, + .destroy_spu = of_destroy_spu, ++ .enable_spu = enable_spu_by_master_run, ++ .disable_spu = disable_spu_by_master_run, + }; +--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c ++++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c +@@ -284,6 +284,11 @@ static void spu_backing_runcntl_write(st + spin_unlock(&ctx->csa.register_lock); + } + ++static void spu_backing_runcntl_stop(struct spu_context *ctx) ++{ ++ spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); ++} ++ + static void spu_backing_master_start(struct spu_context *ctx) + { + struct spu_state *csa = &ctx->csa; +@@ -374,6 +379,7 @@ struct spu_context_ops spu_backing_ops = + .get_ls = spu_backing_get_ls, + .runcntl_read = spu_backing_runcntl_read, + .runcntl_write = spu_backing_runcntl_write, ++ .runcntl_stop = spu_backing_runcntl_stop, + .master_start = spu_backing_master_start, + .master_stop = spu_backing_master_stop, + .set_mfc_query = spu_backing_set_mfc_query, +--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c ++++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c +@@ -220,6 +220,15 @@ static void spu_hw_runcntl_write(struct + spin_unlock_irq(&ctx->spu->register_lock); + } + ++static void spu_hw_runcntl_stop(struct spu_context *ctx) ++{ ++ spin_lock_irq(&ctx->spu->register_lock); ++ out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP); ++ while(in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING) ++ cpu_relax(); ++ spin_unlock_irq(&ctx->spu->register_lock); ++} ++ + static void spu_hw_master_start(struct spu_context *ctx) + { + struct spu *spu = ctx->spu; +@@ -321,6 +330,7 @@ struct spu_context_ops spu_hw_ops = { + .get_ls = spu_hw_get_ls, + .runcntl_read = spu_hw_runcntl_read, + .runcntl_write = spu_hw_runcntl_write, ++ .runcntl_stop = spu_hw_runcntl_stop, + .master_start = spu_hw_master_start, + .master_stop = spu_hw_master_stop, + .set_mfc_query = spu_hw_set_mfc_query, +--- a/arch/powerpc/platforms/cell/spufs/run.c ++++ b/arch/powerpc/platforms/cell/spufs/run.c +@@ -295,7 +295,7 @@ long spufs_run_spu(struct file *file, st + if (mutex_lock_interruptible(&ctx->run_mutex)) + return -ERESTARTSYS; + +- ctx->ops->master_start(ctx); ++ spu_enable_spu(ctx); + ctx->event_return = 0; + + ret = spu_acquire_runnable(ctx, 0); +@@ -336,7 +336,7 @@ long spufs_run_spu(struct file *file, st + } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | + SPU_STATUS_STOPPED_BY_HALT))); + +- ctx->ops->master_stop(ctx); ++ spu_disable_spu(ctx); + ret = spu_run_fini(ctx, npc, &status); + spu_yield(ctx); + +--- a/arch/powerpc/platforms/cell/spufs/spufs.h ++++ b/arch/powerpc/platforms/cell/spufs/spufs.h +@@ -130,6 +130,7 @@ struct spu_context_ops { + char*(*get_ls) (struct spu_context * ctx); + u32 (*runcntl_read) (struct spu_context * ctx); + void (*runcntl_write) (struct spu_context * ctx, u32 data); ++ void (*runcntl_stop) (struct spu_context * ctx); + void (*master_start) (struct spu_context * ctx); + void (*master_stop) (struct spu_context * ctx); + int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); +--- a/arch/powerpc/platforms/ps3/spu.c ++++ b/arch/powerpc/platforms/ps3/spu.c +@@ -28,6 +28,7 @@ + #include + #include + ++#include "../cell/spufs/spufs.h" + #include "platform.h" + + /* spu_management_ops */ +@@ -407,10 +408,23 @@ static int __init ps3_enumerate_spus(int + return result; + } + ++static int ps3_enable_spu(struct spu_context *ctx) ++{ ++ return -ENOSYS; ++} ++ ++static int ps3_disable_spu(struct spu_context *ctx) ++{ ++ ctx->ops->runcntl_stop(ctx); ++ return -ENOSYS; ++} ++ + const struct spu_management_ops spu_management_ps3_ops = { + .enumerate_spus = ps3_enumerate_spus, + .create_spu = ps3_create_spu, + .destroy_spu = ps3_destroy_spu, ++ .enable_spu = ps3_enable_spu, ++ .disable_spu = ps3_disable_spu, + }; + + /* spu_priv1_ops */ +--- a/include/asm-powerpc/spu_priv1.h ++++ b/include/asm-powerpc/spu_priv1.h +@@ -24,6 +24,7 @@ + #include + + struct spu; ++struct spu_context; + + /* access to priv1 registers */ + +@@ -178,6 +179,8 @@ struct spu_management_ops { + int (*enumerate_spus)(int (*fn)(void *data)); + int (*create_spu)(struct spu *spu, void *data); + int (*destroy_spu)(struct spu *spu); ++ int (*enable_spu)(struct spu_context *ctx); ++ int (*disable_spu)(struct spu_context *ctx); + }; + + extern const struct spu_management_ops* spu_management_ops; +@@ -200,6 +203,18 @@ spu_destroy_spu (struct spu *spu) + return spu_management_ops->destroy_spu(spu); + } + ++static inline int ++spu_enable_spu (struct spu_context *ctx) ++{ ++ return spu_management_ops->enable_spu(ctx); ++} ++ ++static inline int ++spu_disable_spu (struct spu_context *ctx) ++{ ++ return spu_management_ops->disable_spu(ctx); ++} ++ + /* + * The declarations folowing are put here for convenience + * and only intended to be used by the platform setup code. --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/22-ps3-rename-processor-id-symbols.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/22-ps3-rename-processor-id-symbols.patch @@ -0,0 +1,178 @@ +Subject: PS3: Rename processor id symbols + +Rename the PS3 static symbols node to ppe_id and cpu to thread_id +to clarify usage. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/interrupt.c | 57 +++++++++++++++++---------------- + 1 file changed, 30 insertions(+), 27 deletions(-) + +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -17,7 +17,7 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +- ++#define DEBUG + #include + #include + #include +@@ -78,14 +78,14 @@ struct ps3_bmp { + /** + * struct ps3_private - a per cpu data structure + * @bmp: ps3_bmp structure +- * @node: HV logical_ppe_id +- * @cpu: HV thread_id ++ * @ppe_id: HV logical_ppe_id ++ * @thread_id: HV thread_id + */ + + struct ps3_private { + struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); +- u64 node; +- unsigned int cpu; ++ u64 ppe_id; ++ u64 thread_id; + }; + + static DEFINE_PER_CPU(struct ps3_private, ps3_private); +@@ -105,7 +105,8 @@ static void ps3_chip_mask(unsigned int v + u64 old; + unsigned long flags; + +- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); ++ pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, ++ pd->thread_id, virq); + + local_irq_save(flags); + asm volatile( +@@ -117,7 +118,7 @@ static void ps3_chip_mask(unsigned int v + : "r" (bit), "r" (p) + : "cc" ); + +- lv1_did_update_interrupt_mask(pd->node, pd->cpu); ++ lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); + local_irq_restore(flags); + } + +@@ -136,7 +137,8 @@ static void ps3_chip_unmask(unsigned int + u64 old; + unsigned long flags; + +- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); ++ pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, ++ pd->thread_id, virq); + + local_irq_save(flags); + asm volatile( +@@ -148,7 +150,7 @@ static void ps3_chip_unmask(unsigned int + : "r" (bit), "r" (p) + : "cc" ); + +- lv1_did_update_interrupt_mask(pd->node, pd->cpu); ++ lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); + local_irq_restore(flags); + } + +@@ -162,7 +164,7 @@ static void ps3_chip_unmask(unsigned int + static void ps3_chip_eoi(unsigned int virq) + { + const struct ps3_private *pd = get_irq_chip_data(virq); +- lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq); ++ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq); + } + + /** +@@ -241,8 +243,8 @@ int ps3_virq_destroy(unsigned int virq) + { + const struct ps3_private *pd = get_irq_chip_data(virq); + +- pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, +- pd->node, pd->cpu, virq); ++ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__, ++ __LINE__, pd->ppe_id, pd->thread_id, virq); + + set_irq_chip_data(virq, NULL); + irq_dispose_mapping(virq); +@@ -278,7 +280,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_bind + + /* Binds outlet to cpu + virq. */ + +- result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); ++ result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq, ++ outlet, 0); + + if (result) { + pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", +@@ -310,12 +313,12 @@ int ps3_irq_plug_destroy(unsigned int vi + int result; + const struct ps3_private *pd = get_irq_chip_data(virq); + +- pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, +- pd->node, pd->cpu, virq); ++ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__, ++ __LINE__, pd->ppe_id, pd->thread_id, virq); + + ps3_chip_mask(virq); + +- result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); ++ result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); + + if (result) + pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", +@@ -657,8 +660,8 @@ static void _dump_bmp(struct ps3_private + unsigned long flags; + + spin_lock_irqsave(&pd->bmp.lock, flags); +- _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); +- _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); ++ _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); ++ _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); + spin_unlock_irqrestore(&pd->bmp.lock, flags); + } + +@@ -669,7 +672,7 @@ static void __maybe_unused _dump_mask(st + unsigned long flags; + + spin_lock_irqsave(&pd->bmp.lock, flags); +- _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); ++ _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); + spin_unlock_irqrestore(&pd->bmp.lock, flags); + } + #else +@@ -722,8 +725,8 @@ static unsigned int ps3_get_irq(void) + plug &= 0x3f; + + if (unlikely(plug) == NO_IRQ) { +- pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, +- pd->cpu); ++ pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__, ++ __LINE__, pd->thread_id); + dump_bmp(&per_cpu(ps3_private, 0)); + dump_bmp(&per_cpu(ps3_private, 1)); + return NO_IRQ; +@@ -753,16 +756,16 @@ void __init ps3_init_IRQ(void) + for_each_possible_cpu(cpu) { + struct ps3_private *pd = &per_cpu(ps3_private, cpu); + +- lv1_get_logical_ppe_id(&pd->node); +- pd->cpu = get_hard_smp_processor_id(cpu); ++ lv1_get_logical_ppe_id(&pd->ppe_id); ++ pd->thread_id = get_hard_smp_processor_id(cpu); + spin_lock_init(&pd->bmp.lock); + +- pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, +- __LINE__, pd->node, pd->cpu, ++ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n", ++ __func__, __LINE__, pd->ppe_id, pd->thread_id, + ps3_mm_phys_to_lpar(__pa(&pd->bmp))); + +- result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, +- ps3_mm_phys_to_lpar(__pa(&pd->bmp))); ++ result = lv1_configure_irq_state_bitmap(pd->ppe_id, ++ pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); + + if (result) + pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/24-powerpc-print-params-value.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/24-powerpc-print-params-value.patch @@ -0,0 +1,22 @@ +Subject: Powerpc: Output params value in early_init_devtree + +Add a printout of the params value to early_init_devtree. +This value is handy to have for comparison when debugging the +bootwrapper code. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/kernel/prom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/prom.c ++++ b/arch/powerpc/kernel/prom.c +@@ -1005,7 +1005,7 @@ static void __init early_reserve_mem(voi + + void __init early_init_devtree(void *params) + { +- DBG(" -> early_init_devtree()\n"); ++ DBG(" -> early_init_devtree(%p)\n", params); + + /* Setup flat device-tree pointer */ + initial_boot_params = params; --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/43-ps3stor_bus.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/43-ps3stor_bus.patch @@ -0,0 +1,439 @@ +Subject: ps3: Storage Driver Core + +From: Geert Uytterhoeven + +Add storage driver core support for the PS3. +PS3 storage devices are a special kind of PS3 system bus devices + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/Kconfig | 4 + drivers/ps3/Makefile | 1 + drivers/ps3/ps3stor_lib.c | 327 +++++++++++++++++++++++++++++++++++++ + include/asm-powerpc/ps3stor.h | 72 ++++++++ + 4 files changed, 404 insertions(+) + +--- a/arch/powerpc/platforms/ps3/Kconfig ++++ b/arch/powerpc/platforms/ps3/Kconfig +@@ -97,4 +97,8 @@ config PS3_SYS_MANAGER + This support is required for system control. In + general, all users will say Y or M. + ++config PS3_STORAGE ++ depends on PPC_PS3 ++ tristate ++ + endmenu +--- a/drivers/ps3/Makefile ++++ b/drivers/ps3/Makefile +@@ -3,3 +3,4 @@ obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o + ps3av_mod-objs += ps3av.o ps3av_cmd.o + obj-$(CONFIG_PPC_PS3) += sys-manager-core.o + obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o ++obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o +--- /dev/null ++++ b/drivers/ps3/ps3stor_lib.c +@@ -0,0 +1,327 @@ ++/* ++ * PS3 Storage Library ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++ ++static irqreturn_t ps3stor_interrupt(int irq, void *data) ++{ ++ struct ps3_storage_device *dev = data; ++ ++ dev->lv1_res = lv1_storage_get_async_status(dev->sbd.dev_id, ++ &dev->lv1_tag, ++ &dev->lv1_status); ++ /* ++ * lv1_status = -1 may mean that ATAPI transport completed OK, but ++ * ATAPI command itself resulted CHECK CONDITION ++ * so, upper layer should issue REQUEST_SENSE to check the sense data ++ */ ++ ++ if (dev->lv1_tag != dev->tag) ++ dev_err(&dev->sbd.core, ++ "%s:%u: tag mismatch, got %lx, expected %lx\n", ++ __func__, __LINE__, dev->lv1_tag, dev->tag); ++ if (dev->lv1_res) ++ dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", ++ __func__, __LINE__, dev->lv1_res, dev->lv1_status); ++ else ++ complete(&dev->irq_done); ++ return IRQ_HANDLED; ++} ++ ++ ++static int ps3stor_probe_access(struct ps3_storage_device *dev) ++{ ++ int res, error; ++ unsigned int i; ++ unsigned long n; ++ ++ if (dev->sbd.match_id == PS3_MATCH_ID_STOR_ROM) { ++ /* special case: CD-ROM is assumed always accessible */ ++ dev->accessible_regions = 1; ++ return 0; ++ } ++ ++ error = -EPERM; ++ for (i = 0; i < dev->num_regions; i++) { ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: checking accessibility of region %u\n", ++ __func__, __LINE__, i); ++ ++ dev->region_idx = i; ++ res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, 0, 1, ++ 0); ++ if (res) { ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: read failed, region %u is not accessible\n", ++ __func__, __LINE__, i); ++ continue; ++ } ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: region %u is accessible\n", ++ __func__, __LINE__, i); ++ set_bit(i, &dev->accessible_regions); ++ ++ /* We can access at least one region */ ++ error = 0; ++ } ++ if (error) ++ return error; ++ ++ n = hweight_long(dev->accessible_regions); ++ if (n > 1) ++ dev_info(&dev->sbd.core, ++ "%s:%u: %lu accessible regions found. Only the first " ++ "one will be used", ++ __func__, __LINE__, n); ++ dev->region_idx = __ffs(dev->accessible_regions); ++ dev_info(&dev->sbd.core, ++ "First accessible region has index %u start %lu size %lu\n", ++ dev->region_idx, dev->regions[dev->region_idx].start, ++ dev->regions[dev->region_idx].size); ++ ++ return 0; ++} ++ ++ ++/** ++ * ps3stor_setup - Setup a storage device before use ++ * @dev: Pointer to a struct ps3_storage_device ++ * @name: Name of the storage driver ++ * ++ * Returns 0 for success, or an error code ++ */ ++int ps3stor_setup(struct ps3_storage_device *dev, const char *name) ++{ ++ int error, res, alignment; ++ enum ps3_dma_page_size page_size; ++ ++ error = ps3_open_hv_device(&dev->sbd); ++ if (error) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: ps3_open_hv_device failed %d\n", __func__, ++ __LINE__, error); ++ goto fail; ++ } ++ ++ error = ps3_sb_event_receive_port_setup(&dev->sbd, PS3_BINDING_CPU_ANY, ++ &dev->irq); ++ if (error) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: ps3_sb_event_receive_port_setup failed %d\n", ++ __func__, __LINE__, error); ++ goto fail_close_device; ++ } ++ ++ error = request_irq(dev->irq, ps3stor_interrupt, IRQF_DISABLED, name, ++ dev); ++ if (error) { ++ dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n", ++ __func__, __LINE__, error); ++ goto fail_sb_event_receive_port_destroy; ++ } ++ ++ alignment = min(__ffs(dev->bounce_size), ++ __ffs((unsigned long)dev->bounce_buf)); ++ if (alignment < 12) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: bounce buffer not aligned (%lx at 0x%p)\n", ++ __func__, __LINE__, dev->bounce_size, dev->bounce_buf); ++ error = -EINVAL; ++ goto fail_free_irq; ++ } else if (alignment < 16) ++ page_size = PS3_DMA_4K; ++ else ++ page_size = PS3_DMA_64K; ++ dev->sbd.d_region = &dev->dma_region; ++ ps3_dma_region_init(&dev->sbd, &dev->dma_region, page_size, ++ PS3_DMA_OTHER, dev->bounce_buf, dev->bounce_size); ++ res = ps3_dma_region_create(&dev->dma_region); ++ if (res) { ++ dev_err(&dev->sbd.core, "%s:%u: cannot create DMA region\n", ++ __func__, __LINE__); ++ error = -ENOMEM; ++ goto fail_free_irq; ++ } ++ ++ dev->bounce_lpar = ps3_mm_phys_to_lpar(__pa(dev->bounce_buf)); ++ dev->bounce_dma = dma_map_single(&dev->sbd.core, dev->bounce_buf, ++ dev->bounce_size, DMA_BIDIRECTIONAL); ++ if (!dev->bounce_dma) { ++ dev_err(&dev->sbd.core, "%s:%u: map DMA region failed\n", ++ __func__, __LINE__); ++ error = -ENODEV; ++ goto fail_free_dma; ++ } ++ ++ error = ps3stor_probe_access(dev); ++ if (error) { ++ dev_err(&dev->sbd.core, "%s:%u: No accessible regions found\n", ++ __func__, __LINE__); ++ goto fail_unmap_dma; ++ } ++ return 0; ++ ++fail_unmap_dma: ++ dma_unmap_single(&dev->sbd.core, dev->bounce_dma, dev->bounce_size, ++ DMA_BIDIRECTIONAL); ++fail_free_dma: ++ ps3_dma_region_free(&dev->dma_region); ++fail_free_irq: ++ free_irq(dev->irq, dev); ++fail_sb_event_receive_port_destroy: ++ ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq); ++fail_close_device: ++ ps3_close_hv_device(&dev->sbd); ++fail: ++ return error; ++} ++EXPORT_SYMBOL_GPL(ps3stor_setup); ++ ++ ++/** ++ * ps3stor_teardown - Tear down a storage device after use ++ * @dev: Pointer to a struct ps3_storage_device ++ */ ++void ps3stor_teardown(struct ps3_storage_device *dev) ++{ ++ int error; ++ ++ dma_unmap_single(&dev->sbd.core, dev->bounce_dma, dev->bounce_size, ++ DMA_BIDIRECTIONAL); ++ ps3_dma_region_free(&dev->dma_region); ++ ++ free_irq(dev->irq, dev); ++ ++ error = ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq); ++ if (error) ++ dev_err(&dev->sbd.core, ++ "%s:%u: destroy event receive port failed %d\n", ++ __func__, __LINE__, error); ++ ++ error = ps3_close_hv_device(&dev->sbd); ++ if (error) ++ dev_err(&dev->sbd.core, ++ "%s:%u: ps3_close_hv_device failed %d\n", __func__, ++ __LINE__, error); ++} ++EXPORT_SYMBOL_GPL(ps3stor_teardown); ++ ++ ++/** ++ * ps3stor_read_write_sectors - read/write from/to a storage device ++ * @dev: Pointer to a struct ps3_storage_device ++ * @lpar: HV logical partition address ++ * @start_sector: First sector to read/write ++ * @sectors: Number of sectors to read/write ++ * @write: Flag indicating write (non-zero) or read (zero) ++ * ++ * Returns 0 for success, -1 in case of failure to submit the command, or ++ * an LV1 status value in case of other errors ++ */ ++u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, ++ u64 start_sector, u64 sectors, int write) ++{ ++ unsigned int region_id = dev->regions[dev->region_idx].id; ++ const char *op = write ? "write" : "read"; ++ int res; ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n", ++ __func__, __LINE__, op, sectors, start_sector); ++ ++ init_completion(&dev->irq_done); ++ res = write ? lv1_storage_write(dev->sbd.dev_id, region_id, ++ start_sector, sectors, 0, lpar, ++ &dev->tag) ++ : lv1_storage_read(dev->sbd.dev_id, region_id, ++ start_sector, sectors, 0, lpar, ++ &dev->tag); ++ if (res) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__, ++ __LINE__, op, res); ++ return -1; ++ } ++ ++ wait_for_completion(&dev->irq_done); ++ if (dev->lv1_status) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, ++ __LINE__, op, dev->lv1_status); ++ return dev->lv1_status; ++ } ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, __LINE__, ++ op); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ps3stor_read_write_sectors); ++ ++ ++/** ++ * ps3stor_send_command - send a device command to a storage device ++ * @dev: Pointer to a struct ps3_storage_device ++ * @cmd: Command number ++ * @arg1: First command argument ++ * @arg2: Second command argument ++ * @arg3: Third command argument ++ * @arg4: Fourth command argument ++ * ++ * Returns 0 for success, -1 in case of failure to submit the command, or ++ * an LV1 status value in case of other errors ++ */ ++u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1, ++ u64 arg2, u64 arg3, u64 arg4) ++{ ++ int res; ++ ++ dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%lx\n", __func__, ++ __LINE__, cmd); ++ ++ init_completion(&dev->irq_done); ++ ++ res = lv1_storage_send_device_command(dev->sbd.dev_id, cmd, arg1, ++ arg2, arg3, arg4, &dev->tag); ++ if (res) { ++ dev_err(&dev->sbd.core, ++ "%s:%u: send_device_command 0x%lx failed %d\n", ++ __func__, __LINE__, cmd, res); ++ return -1; ++ } ++ ++ wait_for_completion(&dev->irq_done); ++ if (dev->lv1_status) ++ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx failed 0x%lx\n", ++ __func__, __LINE__, cmd, dev->lv1_status); ++ else ++ dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx completed\n", ++ __func__, __LINE__, cmd); ++ ++ return dev->lv1_status; ++} ++EXPORT_SYMBOL_GPL(ps3stor_send_command); ++ ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("PS3 Storage Bus Library"); ++MODULE_AUTHOR("Sony Corporation"); +--- /dev/null ++++ b/include/asm-powerpc/ps3stor.h +@@ -0,0 +1,72 @@ ++/* ++ * PS3 Storage Devices ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef _ASM_POWERPC_PS3STOR_H_ ++#define _ASM_POWERPC_PS3STOR_H_ ++ ++#include ++ ++#include ++ ++ ++struct ps3_storage_region { ++ unsigned int id; ++ u64 start; ++ u64 size; ++}; ++ ++struct ps3_storage_device { ++ struct ps3_system_bus_device sbd; ++ ++ struct ps3_dma_region dma_region; ++ unsigned int irq; ++ u64 blk_size; ++ ++ u64 tag; ++ int lv1_res; ++ u64 lv1_tag; ++ u64 lv1_status; ++ struct completion irq_done; ++ ++ unsigned long bounce_size; ++ void *bounce_buf; ++ u64 bounce_lpar; ++ dma_addr_t bounce_dma; ++ ++ unsigned int num_regions; ++ unsigned long accessible_regions; ++ unsigned int region_idx; /* first accessible region */ ++ struct ps3_storage_region regions[0]; /* Must be last */ ++}; ++ ++static inline struct ps3_storage_device *to_ps3_storage_device(struct device *dev) ++{ ++ return container_of(dev, struct ps3_storage_device, sbd.core); ++} ++ ++extern int ps3stor_setup(struct ps3_storage_device *dev, const char *name); ++extern void ps3stor_teardown(struct ps3_storage_device *dev); ++extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, ++ u64 start_sector, u64 sectors, ++ int write); ++extern u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, ++ u64 arg1, u64 arg2, u64 arg3, u64 arg4); ++ ++#endif /* _ASM_POWERPC_PS3STOR_H_ */ --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/37-fb_show_logo_line.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/37-fb_show_logo_line.patch @@ -0,0 +1,107 @@ +Subject: [PATCH 3/8] fbdev: extract fb_show_logo_line() + +Extract the code to draw one line of logos into fb_show_logo_line() + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +Acked-By: James Simmons +--- + drivers/video/fbmem.c | 39 +++++++++++++++++++++++---------------- + 1 files changed, 23 insertions(+), 16 deletions(-) + +--- ps3-linux-2.6.21.orig/drivers/video/fbmem.c ++++ ps3-linux-2.6.21/drivers/video/fbmem.c +@@ -477,22 +477,24 @@ int fb_prepare_logo(struct fb_info *info + return fb_logo.logo->height; + } + +-int fb_show_logo(struct fb_info *info, int rotate) ++static int fb_show_logo_line(struct fb_info *info, int rotate, ++ const struct linux_logo *logo, int y, ++ unsigned int n) + { + u32 *palette = NULL, *saved_pseudo_palette = NULL; + unsigned char *logo_new = NULL, *logo_rotate = NULL; + struct fb_image image; + + /* Return if the frame buffer is not mapped or suspended */ +- if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING || ++ if (logo == NULL || info->state != FBINFO_STATE_RUNNING || + info->flags & FBINFO_MODULE) + return 0; + + image.depth = 8; +- image.data = fb_logo.logo->data; ++ image.data = logo->data; + + if (fb_logo.needs_cmapreset) +- fb_set_logocmap(info, fb_logo.logo); ++ fb_set_logocmap(info, logo); + + if (fb_logo.needs_truepalette || + fb_logo.needs_directpalette) { +@@ -501,17 +503,16 @@ int fb_show_logo(struct fb_info *info, i + return 0; + + if (fb_logo.needs_truepalette) +- fb_set_logo_truepalette(info, fb_logo.logo, palette); ++ fb_set_logo_truepalette(info, logo, palette); + else +- fb_set_logo_directpalette(info, fb_logo.logo, palette); ++ fb_set_logo_directpalette(info, logo, palette); + + saved_pseudo_palette = info->pseudo_palette; + info->pseudo_palette = palette; + } + + if (fb_logo.depth <= 4) { +- logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, +- GFP_KERNEL); ++ logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL); + if (logo_new == NULL) { + kfree(palette); + if (saved_pseudo_palette) +@@ -519,29 +520,35 @@ int fb_show_logo(struct fb_info *info, i + return 0; + } + image.data = logo_new; +- fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); ++ fb_set_logo(info, logo, logo_new, fb_logo.depth); + } + + image.dx = 0; +- image.dy = 0; +- image.width = fb_logo.logo->width; +- image.height = fb_logo.logo->height; ++ image.dy = y; ++ image.width = logo->width; ++ image.height = logo->height; + + if (rotate) { +- logo_rotate = kmalloc(fb_logo.logo->width * +- fb_logo.logo->height, GFP_KERNEL); ++ logo_rotate = kmalloc(logo->width * ++ logo->height, GFP_KERNEL); + if (logo_rotate) + fb_rotate_logo(info, logo_rotate, &image, rotate); + } + +- fb_do_show_logo(info, &image, rotate, num_online_cpus()); ++ fb_do_show_logo(info, &image, rotate, n); + + kfree(palette); + if (saved_pseudo_palette != NULL) + info->pseudo_palette = saved_pseudo_palette; + kfree(logo_new); + kfree(logo_rotate); +- return fb_logo.logo->height; ++ return logo->height; ++} ++ ++int fb_show_logo(struct fb_info *info, int rotate) ++{ ++ return fb_show_logo_line(info, rotate, fb_logo.logo, 0, ++ num_online_cpus()); + } + #else + int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/02-ps3-maybe-unused.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/02-ps3-maybe-unused.patch @@ -0,0 +1,64 @@ +Subject: PS3: Use __maybe_unused + +Change the PS3 debug routines from using the GCC specific +'__attribute__ ((unused))' to the preprocessor macro +__maybe_unused. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/interrupt.c | 4 ++-- + arch/powerpc/platforms/ps3/time.c | 2 +- + drivers/ps3/vuart.c | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/powerpc/platforms/ps3/interrupt.c ++++ b/arch/powerpc/platforms/ps3/interrupt.c +@@ -533,7 +533,7 @@ static void _dump_64_bmp(const char *hea + *p & 0xffff); + } + +-static void __attribute__ ((unused)) _dump_256_bmp(const char *header, ++static void __maybe_unused _dump_256_bmp(const char *header, + const u64 *p, unsigned cpu, const char* func, int line) + { + pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", +@@ -552,7 +552,7 @@ static void _dump_bmp(struct ps3_private + } + + #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) +-static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, ++static void __maybe_unused _dump_mask(struct ps3_private* pd, + const char* func, int line) + { + unsigned long flags; +--- a/arch/powerpc/platforms/ps3/time.c ++++ b/arch/powerpc/platforms/ps3/time.c +@@ -39,7 +39,7 @@ static void _dump_tm(const struct rtc_ti + } + + #define dump_time(_a) _dump_time(_a, __func__, __LINE__) +-static void __attribute__ ((unused)) _dump_time(int time, const char* func, ++static void __maybe_unused _dump_time(int time, const char* func, + int line) + { + struct rtc_time tm; +--- a/drivers/ps3/vuart.c ++++ b/drivers/ps3/vuart.c +@@ -83,7 +83,7 @@ struct ports_bmp { + } __attribute__ ((aligned (32))); + + #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) +-static void __attribute__ ((unused)) _dump_ports_bmp( ++static void __maybe_unused _dump_ports_bmp( + const struct ports_bmp* bmp, const char* func, int line) + { + pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); +@@ -107,7 +107,7 @@ static int ps3_vuart_match_id_to_port(en + } + + #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) +-static void __attribute__ ((unused)) _dump_port_params(unsigned int port_number, ++static void __maybe_unused _dump_port_params(unsigned int port_number, + const char* func, int line) + { + #if defined(DEBUG) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/41-logo-extra-spe-glue-2.6.21.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/41-logo-extra-spe-glue-2.6.21.patch @@ -0,0 +1,81 @@ +Subject: [PATCH 8/8] Cell: Draw SPE helper penguin logos + +Let spu_management_ops.enumerate_spus() return the number of found SPEs +and use that information to draw some little helper penguin logos. + +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Geoff Levand +Cc: Arnd Bergmann +Acked-By: James Simmons +--- + arch/powerpc/platforms/cell/spu_base.c | 6 +++++- + arch/powerpc/platforms/cell/spu_manage.c | 4 +++- + arch/powerpc/platforms/ps3/spu.c | 6 ++++-- + 3 files changed, 12 insertions(+), 4 deletions(-) + +--- ps3-linux-2.6.21.orig/arch/powerpc/platforms/cell/spu_base.c ++++ ps3-linux-2.6.21/arch/powerpc/platforms/cell/spu_base.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -624,12 +625,15 @@ static int __init init_spu_base(void) + + ret = spu_enumerate_spus(create_spu); + +- if (ret) { ++ if (ret < 0) { + printk(KERN_WARNING "%s: Error initializing spus\n", + __FUNCTION__); + goto out_unregister_sysdev_class; + } + ++ if (ret > 0) ++ fb_append_extra_logo(&logo_spe_clut224, ret); ++ + xmon_register_spus(&spu_full_list); + + return 0; +--- ps3-linux-2.6.21.orig/arch/powerpc/platforms/cell/spu_manage.c ++++ ps3-linux-2.6.21/arch/powerpc/platforms/cell/spu_manage.c +@@ -280,6 +280,7 @@ static int __init of_enumerate_spus(int + { + int ret; + struct device_node *node; ++ unsigned int n = 0; + + ret = -ENODEV; + for (node = of_find_node_by_type(NULL, "spe"); +@@ -290,8 +291,9 @@ static int __init of_enumerate_spus(int + __FUNCTION__, node->name); + break; + } ++ n++; + } +- return ret; ++ return ret ? ret : n; + } + + static int __init of_create_spu(struct spu *spu, void *data) +--- ps3-linux-2.6.21.orig/arch/powerpc/platforms/ps3/spu.c ++++ ps3-linux-2.6.21/arch/powerpc/platforms/ps3/spu.c +@@ -401,11 +401,13 @@ static int __init ps3_enumerate_spus(int + } + } + +- if (result) ++ if (result) { + printk(KERN_WARNING "%s:%d: Error initializing spus\n", + __func__, __LINE__); ++ return result; ++ } + +- return result; ++ return num_resource_id; + } + + static int ps3_enable_spu(struct spu_context *ctx) --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/46-ps3stor_flash.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/46-ps3stor_flash.patch @@ -0,0 +1,450 @@ +Subject: ps3: FLASH ROM Storage Driver + +From: Geert Uytterhoeven + +Add a FLASH ROM Storage Driver for the PS3: + - Implemented as a misc character device driver + - Uses a fixed 256 KiB buffer allocated from boot memory as the hypervisor + requires the writing of aligned 256 KiB blocks + +Signed-off-by: Geert Uytterhoeven +--- + arch/powerpc/platforms/ps3/Kconfig | 12 + + drivers/char/Makefile | 2 + drivers/char/ps3flash.c | 401 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 415 insertions(+) + +--- a/arch/powerpc/platforms/ps3/Kconfig ++++ b/arch/powerpc/platforms/ps3/Kconfig +@@ -123,4 +123,16 @@ config PS3_ROM + This support is required to access the PS3 BD/DVD/CD-ROM drive. + In general, all users will say Y or M. + ++config PS3_FLASH ++ tristate "PS3 FLASH ROM Storage Driver" ++ depends on PPC_PS3 ++ select PS3_STORAGE ++ default y ++ help ++ Include support for the PS3 FLASH ROM Storage. ++ ++ This support is required to access the PS3 FLASH ROM, which ++ contains the boot loader and some boot options. ++ In general, all users will say Y or M. ++ + endmenu +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -104,6 +104,8 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ + obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o + obj-$(CONFIG_TCG_TPM) += tpm/ + ++obj-$(CONFIG_PS3_FLASH) += ps3flash.o ++ + # Files generated that shall be removed upon make clean + clean-files := consolemap_deftbl.c defkeymap.c + +--- /dev/null ++++ b/drivers/char/ps3flash.c +@@ -0,0 +1,401 @@ ++/* ++ * PS3 FLASH ROM Storage Driver ++ * ++ * Copyright (C) 2007 Sony Computer Entertainment Inc. ++ * Copyright 2007 Sony Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; version 2 of the License. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++#define DEVICE_NAME "ps3flash" ++ ++#define FLASH_BLOCK_SIZE (256*1024) ++ ++ ++struct ps3flash_private { ++ struct mutex mutex; ++}; ++#define ps3flash_priv(dev) ((dev)->sbd.core.driver_data) ++ ++static struct ps3_storage_device *ps3flash_dev; ++ ++static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, ++ u64 lpar, u64 start_sector, ++ u64 sectors, int write) ++{ ++ const char *op = write ? "write" : "read"; ++ u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, ++ write); ++ if (res) { ++ dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, ++ __LINE__, op, res); ++ return -EIO; ++ } ++ return sectors; ++} ++ ++static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, ++ u64 start_sector, u64 sectors, ++ unsigned int sector_offset) ++{ ++ u64 max_sectors, lpar; ++ ++ max_sectors = dev->bounce_size / dev->blk_size; ++ if (sectors > max_sectors) { ++ dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n", ++ __func__, __LINE__, max_sectors); ++ sectors = max_sectors; ++ } ++ ++ lpar = dev->bounce_lpar + sector_offset * dev->blk_size; ++ return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, ++ 0); ++} ++ ++static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, ++ u64 start_sector) ++{ ++ u64 sectors = dev->bounce_size / dev->blk_size; ++ return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, ++ sectors, 1); ++} ++ ++static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) ++{ ++ struct ps3_storage_device *dev = ps3flash_dev; ++ u64 size = dev->regions[dev->region_idx].size*dev->blk_size; ++ ++ switch (origin) { ++ case 1: ++ offset += file->f_pos; ++ break; ++ case 2: ++ offset += size; ++ break; ++ } ++ if (offset < 0) ++ return -EINVAL; ++ ++ file->f_pos = offset; ++ return file->f_pos; ++} ++ ++static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, ++ loff_t *pos) ++{ ++ struct ps3_storage_device *dev = ps3flash_dev; ++ struct ps3flash_private *priv = ps3flash_priv(dev); ++ u64 size, start_sector, end_sector, offset; ++ ssize_t sectors_read; ++ size_t remaining, n; ++ ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", ++ __func__, __LINE__, count, *pos, buf); ++ ++ size = dev->regions[dev->region_idx].size*dev->blk_size; ++ if (*pos >= size || !count) ++ return 0; ++ ++ if (*pos+count > size) { ++ dev_dbg(&dev->sbd.core, ++ "%s:%u Truncating count from %zu to %llu\n", __func__, ++ __LINE__, count, size-*pos); ++ count = size-*pos; ++ } ++ ++ start_sector = do_div_llr(*pos, dev->blk_size, &offset); ++ end_sector = DIV_ROUND_UP(*pos+count, dev->blk_size); ++ ++ remaining = count; ++ do { ++ mutex_lock(&priv->mutex); ++ ++ sectors_read = ps3flash_read_sectors(dev, start_sector, ++ end_sector-start_sector, ++ 0); ++ if (sectors_read < 0) { ++ mutex_unlock(&priv->mutex); ++ return sectors_read; ++ } ++ ++ n = min(remaining, sectors_read*dev->blk_size-offset); ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", ++ __func__, __LINE__, n, dev->bounce_buf+offset, buf); ++ if (copy_to_user(buf, dev->bounce_buf+offset, n)) { ++ mutex_unlock(&priv->mutex); ++ return -EFAULT; ++ } ++ ++ mutex_unlock(&priv->mutex); ++ ++ *pos += n; ++ buf += n; ++ remaining -= n; ++ start_sector += sectors_read; ++ offset = 0; ++ } while (remaining > 0); ++ ++ return count; ++} ++ ++static ssize_t ps3flash_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *pos) ++{ ++ struct ps3_storage_device *dev = ps3flash_dev; ++ struct ps3flash_private *priv = ps3flash_priv(dev); ++ u64 size, chunk_sectors, start_write_sector, end_write_sector, ++ end_read_sector, start_read_sector, head, tail, offset; ++ ssize_t res; ++ size_t remaining, n; ++ ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", ++ __func__, __LINE__, count, *pos, buf); ++ ++ size = dev->regions[dev->region_idx].size*dev->blk_size; ++ if (*pos >= size || !count) ++ return 0; ++ ++ if (*pos+count > size) { ++ dev_dbg(&dev->sbd.core, ++ "%s:%u Truncating count from %zu to %llu\n", __func__, ++ __LINE__, count, size-*pos); ++ count = size-*pos; ++ } ++ ++ chunk_sectors = dev->bounce_size / dev->blk_size; ++ ++ start_write_sector = do_div_llr(*pos, dev->bounce_size, &offset) * ++ chunk_sectors; ++ end_write_sector = DIV_ROUND_UP(*pos+count, dev->bounce_size) * ++ chunk_sectors; ++ ++ end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size); ++ start_read_sector = (*pos+count) / dev->blk_size; ++ ++ /* ++ * As we have to write in 256 KiB chunks, while we can read in blk_size ++ * (usually 512 bytes) chunks, we perform the following steps: ++ * 1. Read from start_write_sector to end_read_sector ("head") ++ * 2. Read from start_read_sector to end_write_sector ("tail") ++ * 3. Copy data to buffer ++ * 4. Write from start_write_sector to end_write_sector ++ * All of this is complicated by using only one 256 KiB bounce buffer. ++ */ ++ ++ head = end_read_sector-start_write_sector; ++ tail = end_write_sector-start_read_sector; ++ ++ remaining = count; ++ do { ++ mutex_lock(&priv->mutex); ++ ++ if (end_read_sector >= start_read_sector) { ++ /* Merge head and tail */ ++ dev_dbg(&dev->sbd.core, ++ "Merged head and tail: %lu sectors at %lu\n", ++ chunk_sectors, start_write_sector); ++ res = ps3flash_read_sectors(dev, start_write_sector, ++ chunk_sectors, 0); ++ if (res < 0) ++ goto fail; ++ } else { ++ if (head) { ++ /* Read head */ ++ dev_dbg(&dev->sbd.core, "head: %lu sectors at %lu\n", ++ head, start_write_sector); ++ res = ps3flash_read_sectors(dev, ++ start_write_sector, ++ head, 0); ++ if (res < 0) ++ goto fail; ++ } ++ if (start_read_sector < ++ start_write_sector+chunk_sectors) { ++ /* Read tail */ ++ dev_dbg(&dev->sbd.core, ++ "tail: %lu sectors at %lu\n", tail, ++ start_read_sector-start_write_sector); ++ res = ps3flash_read_sectors(dev, ++ start_read_sector, ++ tail, ++ start_read_sector-start_write_sector); ++ if (res < 0) ++ goto fail; ++ } ++ } ++ ++ n = min(remaining, dev->bounce_size-offset); ++ dev_dbg(&dev->sbd.core, ++ "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n", ++ __func__, __LINE__, n, buf, dev->bounce_buf+offset); ++ if (copy_from_user(dev->bounce_buf+offset, buf, n)) { ++ res = -EFAULT; ++ goto fail; ++ } ++ ++ res = ps3flash_write_chunk(dev, start_write_sector); ++ if (res < 0) ++ goto fail; ++ ++ mutex_unlock(&priv->mutex); ++ ++ *pos += n; ++ buf += n; ++ remaining -= n; ++ start_write_sector += chunk_sectors; ++ head = 0; ++ offset = 0; ++ } while (remaining > 0); ++ ++ return count; ++ ++fail: ++ mutex_unlock(&priv->mutex); ++ return res; ++} ++ ++ ++static const struct file_operations ps3flash_fops = { ++ .owner = THIS_MODULE, ++ .llseek = ps3flash_llseek, ++ .read = ps3flash_read, ++ .write = ps3flash_write, ++}; ++ ++static struct miscdevice ps3flash_misc = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = DEVICE_NAME, ++ .fops = &ps3flash_fops, ++}; ++ ++static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ struct ps3flash_private *priv; ++ int error; ++ unsigned long tmp; ++ ++ tmp = dev->regions[dev->region_idx].start*dev->blk_size; ++ if (tmp % FLASH_BLOCK_SIZE) { ++ dev_err(&dev->sbd.core, ++ "%s:%u region start %lu is not aligned\n", __func__, ++ __LINE__, tmp); ++ return -EINVAL; ++ } ++ tmp = dev->regions[dev->region_idx].size*dev->blk_size; ++ if (tmp % FLASH_BLOCK_SIZE) { ++ dev_err(&dev->sbd.core, ++ "%s:%u region size %lu is not aligned\n", __func__, ++ __LINE__, tmp); ++ return -EINVAL; ++ } ++ ++ /* use static buffer, kmalloc cannot allocate 256 KiB */ ++ if (!ps3flash_bounce_buffer.address) ++ return -ENOMEM; ++ ++ if (ps3flash_dev) { ++ dev_err(&dev->sbd.core, ++ "Only one FLASH device is supported\n"); ++ return -EBUSY; ++ } ++ ++ ps3flash_dev = dev; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) { ++ error = -ENOMEM; ++ goto fail; ++ } ++ ++ ps3flash_priv(dev) = priv; ++ mutex_init(&priv->mutex); ++ ++ dev->bounce_size = ps3flash_bounce_buffer.size; ++ dev->bounce_buf = ps3flash_bounce_buffer.address; ++ ++ error = ps3stor_setup(dev, DEVICE_NAME); ++ if (error) ++ goto fail_free_priv; ++ ++ error = misc_register(&ps3flash_misc); ++ if (error) { ++ dev_err(&dev->sbd.core, "%s:%u: misc_register failed %d\n", ++ __func__, __LINE__, error); ++ goto fail_teardown; ++ } ++ ++ dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", ++ __func__, __LINE__, ps3flash_misc.minor); ++ return 0; ++ ++fail_teardown: ++ ps3stor_teardown(dev); ++fail_free_priv: ++ kfree(priv); ++fail: ++ ps3flash_dev = NULL; ++ return error; ++} ++ ++static int ps3flash_remove(struct ps3_system_bus_device *_dev) ++{ ++ struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); ++ ++ misc_deregister(&ps3flash_misc); ++ ps3stor_teardown(dev); ++ kfree(ps3flash_priv(dev)); ++ ps3flash_dev = NULL; ++ return 0; ++} ++ ++ ++static struct ps3_system_bus_driver ps3flash = { ++ .match_id = PS3_MATCH_ID_STOR_FLASH, ++ .core.name = DEVICE_NAME, ++ .core.owner = THIS_MODULE, ++ .probe = ps3flash_probe, ++ .remove = ps3flash_remove, ++ .shutdown = ps3flash_remove, ++}; ++ ++ ++static int __init ps3flash_init(void) ++{ ++ return ps3_system_bus_driver_register(&ps3flash); ++} ++ ++static void __exit ps3flash_exit(void) ++{ ++ ps3_system_bus_driver_unregister(&ps3flash); ++} ++ ++module_init(ps3flash_init); ++module_exit(ps3flash_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("PS3 FLASH ROM Storage Driver"); ++MODULE_AUTHOR("Sony Corporation"); ++MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/patchset/01-ps3-rename-ipi-symbols.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/patchset/01-ps3-rename-ipi-symbols.patch @@ -0,0 +1,60 @@ +Subject: PS3: Rename IPI symbols + +Rename the PS3 static symbol virqs to ps3_ipi_virqs to aid in +debugging. + +Signed-off-by: Geoff Levand +--- + arch/powerpc/platforms/ps3/smp.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/platforms/ps3/smp.c ++++ b/arch/powerpc/platforms/ps3/smp.c +@@ -39,11 +39,11 @@ static irqreturn_t ipi_function_handler( + } + + /** +- * virqs - a per cpu array of virqs for ipi use ++ * ps3_ipi_virqs - a per cpu array of virqs for ipi use + */ + + #define MSG_COUNT 4 +-static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); ++static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]); + + static const char *names[MSG_COUNT] = { + "ipi call", +@@ -62,7 +62,7 @@ static void do_message_pass(int target, + return; + } + +- virq = per_cpu(virqs, target)[msg]; ++ virq = per_cpu(ps3_ipi_virqs, target)[msg]; + result = ps3_send_event_locally(virq); + + if (result) +@@ -94,13 +94,13 @@ static int ps3_smp_probe(void) + static void __init ps3_smp_setup_cpu(int cpu) + { + int result; +- unsigned int *virqs = per_cpu(virqs, cpu); ++ unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); + int i; + + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + + /* +- * Check assumptions on virqs[] indexing. If this ++ * Check assumptions on ps3_ipi_virqs[] indexing. If this + * check fails, then a different mapping of PPC_MSG_ + * to index needs to be setup. + */ +@@ -132,7 +132,7 @@ static void __init ps3_smp_setup_cpu(int + + void ps3_smp_cleanup_cpu(int cpu) + { +- unsigned int *virqs = per_cpu(virqs, cpu); ++ unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); + int i; + + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/config.powerpc +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/config.powerpc @@ -0,0 +1,3355 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22.9 +# Tue Oct 2 13:05:42 2007 +# +CONFIG_PPC64=y +CONFIG_PPC_PM_NEEDS_RTC_LIB=y +CONFIG_64BIT=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_ARCH_HAS_ILOG2_U64=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC64_SWSUSP=y + +# +# Processor support +# +# CONFIG_POWER4_ONLY is not set +CONFIG_POWER3=y +CONFIG_POWER4=y +CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +CONFIG_PPC_DCR_MMIO=y +CONFIG_PPC_DCR=y +CONFIG_PPC_OF_PLATFORM_PCI=y +CONFIG_ALTIVEC=y +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_MM_SLICES=y +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_SMP=y +CONFIG_NR_CPUS=32 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CPUSETS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Block layer +# +CONFIG_BLOCK=y +CONFIG_BLK_DEV_IO_TRACE=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# Platform support +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_EMBEDDED6xx is not set +# CONFIG_APUS is not set +CONFIG_PPC_PSERIES=y +CONFIG_PPC_SPLPAR=y +CONFIG_EEH=y +CONFIG_SCANLOG=m +CONFIG_LPARCFG=y +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set +CONFIG_PPC_PMAC=y +CONFIG_PPC_PMAC64=y +CONFIG_PPC_MAPLE=y +CONFIG_PPC_PASEMI=y + +# +# PA Semi PWRficient options +# +CONFIG_PPC_PASEMI_IOMMU=y +CONFIG_PPC_PASEMI_MDIO=m +CONFIG_PPC_CELLEB=y +CONFIG_PPC_PS3=y + +# +# PS3 Platform Options +# +CONFIG_PS3_ADVANCED=y +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y +CONFIG_PS3_SYS_MANAGER=y +CONFIG_PS3_STORAGE=m +CONFIG_PS3_DISK=m +CONFIG_PS3_ROM=m +CONFIG_PS3_FLASH=m +CONFIG_PPC_CELL=y +CONFIG_PPC_CELL_NATIVE=y +CONFIG_PPC_IBM_CELL_BLADE=y + +# +# Cell Broadband Engine options +# +CONFIG_SPU_FS=y +CONFIG_SPU_FS_64K_LS=y +CONFIG_SPU_BASE=y +CONFIG_CBE_RAS=y +CONFIG_CBE_THERM=m +# CONFIG_CBE_CPUFREQ is not set +# CONFIG_PQ2ADS is not set +CONFIG_PPC_NATIVE=y +CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_PPC_UDBG_BEAT=y +CONFIG_XICS=y +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +CONFIG_PPC_I8259=y +CONFIG_U3_DART=y +CONFIG_PPC_RTAS=y +CONFIG_RTAS_ERROR_LOGGING=y +CONFIG_RTAS_PROC=y +CONFIG_RTAS_FLASH=m +CONFIG_PPC_PMI=m +CONFIG_MMIO_NVRAM=y +CONFIG_MPIC_U3_HT_IRQS=y +CONFIG_IBMVIO=y +CONFIG_IBMEBUS=y +# CONFIG_PPC_MPC106 is not set +CONFIG_PPC_970_NAP=y +CONFIG_PPC_INDIRECT_IO=y +CONFIG_GENERIC_IOMAP=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPU Frequency drivers +# +CONFIG_CPU_FREQ_PMAC64=y +CONFIG_PPC_PASEMI_CPUFREQ=y +# CONFIG_CPM2 is not set + +# +# Kernel options +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_FORCE_MAX_ZONEORDER=13 +# CONFIG_IOMMU_VMERGE is not set +# CONFIG_HOTPLUG_CPU is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_IRQ_ALL_CPUS=y +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=4 +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_NODES_SPAN_OTHER_NODES=y +CONFIG_PPC_HAS_HASH_64K=y +# CONFIG_PPC_64K_PAGES is not set +CONFIG_SCHED_SMT=y +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SYSFS_DEPRECATED=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_SECCOMP=y +# CONFIG_WANT_DEVICE_TREE is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_PPC_INDIRECT_PCI is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=m +# CONFIG_HOTPLUG_PCI is not set +CONFIG_KERNEL_START=0xc000000000000000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_NET_DCCPPROBE=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_FIFO=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_NET_TCPPROBE=m +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_YAM=m +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m + +# +# Old SIR device drivers +# + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m +CONFIG_FIB_RULES=y + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_OF=m +CONFIG_MTD_PCI=m +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_OTP is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +CONFIG_PARIDE=m + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +# CONFIG_BLK_CPQ_DA is not set +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m + +# +# Misc devices +# +CONFIG_PHANTOM=m +CONFIG_SGI_IOC4=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDEPCI_PCIBUS_ORDER 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_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=m +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_CMD64X=m +# 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=m +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=m +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_SC1200=m +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +CONFIG_BLK_DEV_NS87415=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +# CONFIG_PDC202XX_BURST 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_SL82C105 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLK_DEV_TC86C001=m +CONFIG_BLK_DEV_CELLEB=m +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set + +# +# SCSI low-level drivers +# +CONFIG_ISCSI_TCP=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_ARCMSR=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_HPTIOP=m +# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_IBMVSCSI=m +CONFIG_SCSI_IBMVSCSIS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_DC390T is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_SRP=m + +# +# PCMCIA SCSI adapter support +# +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_ATA=m +CONFIG_ATA_NONSTANDARD=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_SVW=m +CONFIG_ATA_PIIX=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SX4=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SATA_INIC162X=m +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +CONFIG_PATA_CS5520=m +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +CONFIG_PATA_EFAR=m +CONFIG_ATA_GENERIC=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +CONFIG_PATA_IT821X=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_NETCELL=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RZ1000=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +# CONFIG_PATA_VIA is not set +CONFIG_PATA_WINBOND=m +CONFIG_PATA_SCC=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m +# CONFIG_DM_DELAY is not set + +# +# Fusion MPT device support +# +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set + +# +# Controllers +# +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocols +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m + +# +# I2O device support +# +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_I2O_CONFIG is not set +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_ADB_PMU=y +# CONFIG_ADB_PMU_LED is not set +CONFIG_PMAC_SMU=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_THERM_PM72=m +CONFIG_WINDFARM=m +CONFIG_WINDFARM_PM81=m +CONFIG_WINDFARM_PM91=m +CONFIG_WINDFARM_PM112=m +CONFIG_PMAC_RACKMETER=m + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_FIXED_PHY=m +# CONFIG_FIXED_MII_10_FDX is not set +# CONFIG_FIXED_MII_100_FDX is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_HP100=m +CONFIG_IBMVETH=m +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +# CONFIG_PCNET32_NAPI is not set +CONFIG_AMD8111_ETH=m +# CONFIG_AMD8111E_NAPI is not set +CONFIG_ADAPTEC_STARFIRE=m +# CONFIG_ADAPTEC_STARFIRE_NAPI is not set +CONFIG_B44=m +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_DGRS=m +CONFIG_EEPRO100=m +CONFIG_E100=m +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_SIS900=m +CONFIG_EPIC100=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_VIA_RHINE_NAPI is not set +CONFIG_SC92031=m +CONFIG_NET_POCKET=y +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_NETDEV_1000=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +# CONFIG_R8169_NAPI is not set +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SK98LIN is not set +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m +CONFIG_BNX2=m +CONFIG_SPIDER_NET=m +CONFIG_GELIC_NET=m +CONFIG_GELIC_WIRELESS=y +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_NETDEV_10000=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T1_NAPI=y +CONFIG_CHELSIO_T3=m +CONFIG_EHEA=m +CONFIG_IXGB=m +# CONFIG_IXGB_NAPI is not set +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set +CONFIG_MYRI10GE=m +CONFIG_NETXEN_NIC=m +# CONFIG_PASEMI_MAC is not set +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_ABYSS=m + +# +# Wireless LAN +# +CONFIG_WLAN_PRE80211=y +CONFIG_STRIP=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_WLAN_80211=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_APPLE_AIRPORT=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_NORTEL_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCMCIA_HERMES is not set +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PRISM54=m +CONFIG_USB_ZD1201=m +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_BCM43XX=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +CONFIG_HDLC=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_X25=m +CONFIG_PCI200SYN=m +CONFIG_WANXL=m +CONFIG_PC300=m +CONFIG_PC300_MLPPP=y + +# +# Cyclades-PC300 MLPPP support is disabled. +# + +# +# Refer to the file README.mlppp, provided by PC300 package. +# +# CONFIG_PC300TOO is not set +CONFIG_FARSYNC=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +CONFIG_LAPBETHER=m +CONFIG_X25_ASY=m +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_FORE200E_PCA=y +CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E=m +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_FDDI=y +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_SKFP=m +CONFIG_HIPPI=y +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +CONFIG_SHAPER=m +CONFIG_NETCONSOLE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m + +# +# 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=m +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_COMPUTONE=m +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +CONFIG_DIGIEPCA=m +CONFIG_MOXA_INTELLIO=m +# CONFIG_MOXA_SMARTIO is not set +CONFIG_MOXA_SMARTIO_NEW=m +# CONFIG_ISI is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +CONFIG_SPECIALIX=m +# CONFIG_SPECIALIX_RTSCTS is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_PCI=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_SERIAL_ICOM=m +CONFIG_SERIAL_TXX9=y +CONFIG_HAS_TXX9_SERIAL=y +CONFIG_SERIAL_TXX9_NR_UARTS=6 +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_SERIAL_TXX9_STDSERIAL is not set +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_OF_PLATFORM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_TIPAR=m +CONFIG_HVC_DRIVER=y +CONFIG_HVC_CONSOLE=y +CONFIG_HVC_RTAS=y +# CONFIG_HVC_BEAT is not set +CONFIG_HVCS=m + +# +# IPMI +# +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_WATCHDOG_RTAS=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_PASEMI=m +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HANGCHECK_TIMER=m + +# +# TPM devices +# +CONFIG_TCG_TPM=m +CONFIG_TCG_ATMEL=m +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_POULSBO is not set +CONFIG_I2C_ISA=m +CONFIG_I2C_POWERMAC=y +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PASEMI=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m + +# +# SPI Protocol Masters +# +CONFIG_SPI_AT25=m +CONFIG_SPI_SPIDEV=m + +# +# Dallas's 1-wire bus +# +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_SM501=m + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m + +# +# Video decoders +# +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_TUNER_3036=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_OSS=m +CONFIG_VIDEO_SAA7134_DVB=m +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_29XXX=y +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +# CONFIG_USB_OV511 is not set +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m +CONFIG_USB_DSBR=m +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_STV0299=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_TDA10086=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m + +# +# Tuners/PLL support +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_TUNER_MT2060=m + +# +# Miscellaneous devices +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_TUA6100=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# +CONFIG_VGASTATE=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SVGALIB=m +CONFIG_FB_MACMODES=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_OF=y +CONFIG_FB_ASILIANT=y +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=y +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=y +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_VOODOO1=y +CONFIG_FB_VT8623=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_TRIDENT_ACCEL=y +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +CONFIG_FB_SM501=m +CONFIG_FB_IBM_GXT4500=m +CONFIG_FB_PS3=y +CONFIG_FB_PS3_DEFAULT_SIZE_M=18 +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m + +# +# PCI devices +# +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_FM801_TEA575X=m +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL=y +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y +CONFIG_SND_AC97_POWER_SAVE=y + +# +# ALSA PowerMac devices +# +CONFIG_SND_POWERMAC=m +CONFIG_SND_POWERMAC_AUTO_DRC=y + +# +# ALSA PowerPC devices +# +CONFIG_SND_PS3=m +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 + +# +# Apple Onboard Audio driver +# +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m +CONFIG_SND_AOA_SOUNDBUS=m +CONFIG_SND_AOA_SOUNDBUS_I2S=m + +# +# USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y + +# +# PCMCIA devices +# +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m + +# +# System on Chip audio support +# +CONFIG_SND_SOC=m + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_OSS_OBSOLETE is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set +CONFIG_AC97_BUS=m + +# +# HID Devices +# +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT_POWERBOOK=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +CONFIG_USB_KBD=m +CONFIG_USB_MOUSE=m + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MON=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=m +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m + +# +# MMC/SD/SDIO support, can only select one arch from MMC and MSS +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=m + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +# CONFIG_MSS is not set + +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y + +# +# InfiniBand support +# +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_EHCA=m +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_TEST=m + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_V3020=m + +# +# on-CPU RTC drivers +# + +# +# DMA Engine support +# +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=m + +# +# Auxiliary Display support +# +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_MINIX_FS=m +CONFIG_ROMFS_FS=m +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m + +# +# Layered filesystems +# +CONFIG_ECRYPT_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +# CONFIG_EFI_PARTITION is not set +CONFIG_SYSV68_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Distributed Lock Manager +# +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_UCC_SLOW is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y + +# +# Instrumentation Support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m +CONFIG_KPROBES=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_HCALL_STATS is not set +# CONFIG_DEBUGGER is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_KEYS_COMPAT=y + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_TEST=m + +# +# Hardware crypto devices +# +# CONFIG_NIU is not set --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/cell/vars +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/cell/vars @@ -0,0 +1,6 @@ +arch="powerpc" +supported="PowerPC Cell" +desc="PowerPC Cell" +target="Supports PowerPC Cell (Including PS3)" +bootloader="yaboot" +provides="rhcs-modules2-1" --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/rules +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/rules @@ -0,0 +1 @@ +# Nothing special here --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0001-Thermal-Poulsbo-ACPI-thermal-optimisation-framework.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0001-Thermal-Poulsbo-ACPI-thermal-optimisation-framework.patch @@ -0,0 +1,2449 @@ +From fbf97c825cb58771da2a4803b6ad323629030367 Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: ACPI thermal optimisation framework + +-Moved the definitions to header file +-Provided support for sysfs interface to thermal driver +-Provided support for userspace application to handle thermal management +-Provided a unified interface for CPU throttling (acpi_set_passive_thermal_limit) +-Provided interfaces for other components like CPU to register with thermal driver + +Signed-off-by: Sujith Thomas +--- + .../thermal/thermal-ext-add-device-howto.txt | 139 ++ + .../thermal/thermal-ext-add-sensor-howto.txt | 112 ++ + Documentation/thermal/thermal-extensions.txt | 151 +++ + drivers/acpi/Kconfig | 42 +- + drivers/acpi/thermal.c | 1400 ++++++++++++++++++-- + include/linux/thermal.h | 355 +++++ + 6 files changed, 2070 insertions(+), 129 deletions(-) + create mode 100644 Documentation/thermal/thermal-ext-add-device-howto.txt + create mode 100644 Documentation/thermal/thermal-ext-add-sensor-howto.txt + create mode 100644 Documentation/thermal/thermal-extensions.txt + create mode 100644 include/linux/thermal.h + +diff --git a/Documentation/thermal/thermal-ext-add-device-howto.txt b/Documentation/thermal/thermal-ext-add-device-howto.txt +new file mode 100644 +index 0000000..6d72b5a +--- /dev/null ++++ b/Documentation/thermal/thermal-ext-add-device-howto.txt +@@ -0,0 +1,139 @@ ++How-to add participant for thermal extensions ++============================================ ++ ++Written by Sujith Thomas ++ ++Updated: 30 July 2007 ++ ++Copyright (c) 2007 Intel Corporation ++ ++ ++0. Introduction ++ ++The thermal extensions provide a set of interfaces for devices to register ++with the thermal management solution and to be a part of it. This how-to ++focusses on enabling a new class of device to participate in thermal ++management. ++ ++1. Device interface functions ++ ========================== ++ ++1.1 Register device driver ++ ++This step has to be done by all drivers upon initialization. This registers ++a set of callbacks with the thermalzone driver. This needs to be done ++only once for a particular class of device ++ ++/* ++ * thermal_register_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance as defined in thermal.h ++ */ ++int thermal_register_device_driver(struct thermal_device_driver* dd); ++ ++1.2 Unregister device driver ++ ++This step has to be done by all drivers upon exit. This removes a ++particular class of devices from participating in thermal management. ++Logical flow is that all the instances should be unregistered using ++thermal_unregister_device before unregistering the driver ++ ++/* ++ * thermal_unregister_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance used for registration ++ */ ++int thermal_unregister_device_driver(struct thermal_device_driver* dd); ++ ++1.3 Register device ++ ++This step has to be done by all devices upon enumeration. Upon enumeration ++ACPI will be detecting devices like CPU0,CPU1 etc. This would be a nice ++place to call this interface function and get registered with thermal zone ++driver. ++ ++/* ++ * thermal_register_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to register ++ * name : ACPI name like CPU0 ++ * class : class (same as driver class) ++ * private: context of the device ++ * return : a pointer to new thermal device ++ */ ++struct thermal_device* thermal_register_device(const char* name,enum participant_class class ++ ,void* private); ++ ++ ++1.4 Unregister device ++ ++This needs to be done by all devices upon ACPI remove. Whenever an ACPI device ++is getting removed a callback function in the driver will be getting called. ++This will be the nice place for unregistering device from thermal management. ++ ++/* ++ * thermal_unregister_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to unregister ++ * name : ACPI thermal device * ++ */ ++int thermal_unregister_device(struct thermal_device* td); ++ ++2. Device callback functions ++ ========================= ++In addition to these calls driver needs to implement the following ++callback functions that are defined in struct thermal_device_ops ++ ++struct thermal_device_ops { ++ thermal_device_set_throttle_limit setthrottlelimit; //Set new throttle limit ++ thermal_device_get_throttle_limit getthrottlelimit; //Get current throttle limit ++ thermal_device_get_max_throttle_limit getmaxthrottlelimit; //Get maximum suppoted throttle state ++ thermal_device_get_caps getcaps ; //Get device capabilities ++}; ++ ++2.1 Get throttle limit ++ ++/* ++ * device_get_throttle_limit ++ * ----------------------------- ++ * call back function for getting the device's current throttle limit ++ * data : device context ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int device_get_throttle_limit(void *data, char *buf) ++ ++2.2 Set throttle limit ++ ++/* ++ * device_set_throttle_limit ++ * ----------------------------- ++ * call back function for setting the device's new throttle limit ++ * type : Absolute throttle value or Relative throttle step ++ * data : device context ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int device_set_throttle_limit(enum throttle_set_type type,void *data, const char *buf) ++ ++2.3 Get maximum throttle limit ++ ++/* ++ * device_get_maxthrottle_limit ++ * ----------------------------- ++ * call back function for getting the device's maximum throttle limit ++ * data : device context ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int device_get_maxthrottle_limit(void *data, char *buf) ++ ++2.4 Get device capabilities ++ ++/* ++ * device_get_caps ++ * ----------------------------- ++ * call back function for getting the device's capabilities ++ * data : device context ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int device_get_caps(void *data, char *buf) +\ No newline at end of file +diff --git a/Documentation/thermal/thermal-ext-add-sensor-howto.txt b/Documentation/thermal/thermal-ext-add-sensor-howto.txt +new file mode 100644 +index 0000000..9468b45 +--- /dev/null ++++ b/Documentation/thermal/thermal-ext-add-sensor-howto.txt +@@ -0,0 +1,112 @@ ++How-to add sensor for thermal extensions ++============================================ ++ ++Written by Sujith Thomas ++ ++Updated: 30 July 2007 ++ ++Copyright (c) 2007 Intel Corporation ++ ++ ++0. Introduction ++ ++The thermal extensions provide a set of interface for platform specific ++sensor driver to register with the thermal management solution and to be ++a part of it. The main role of the platform sensor driver is to provide ++programming interface for AUX trips to the user application. This how-to ++focusses on writing a new sensor driver for a new platform. ++ ++ ++1 Sensor driver interfaces ++=========================== ++ ++1.1 Register sensor driver ++ ++This step has to be done by all drivers upon initialization. This registers ++a set of callbacks with the thermalzone driver for programming the AUX ++trips. ++ ++/* ++ * thermal_register_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to register ++ * class: class of sensor like CPU sensor or skin sensor ++ * name : ACPI Thermal zone name like TZ00 ++ * ops: callback function as defined in platform sensor driver ++ */ ++int thermal_register_sensor(enum participant_class class ++ ,const char* name, struct thermal_sensor_ops* ops); ++ ++ ++1.2 Unregister sensor driver ++ ++This step needs to be done upon sensor driver exit. This removes the ++association of a thermal sensor from the thermal management solution. ++ ++/* ++ * thermal_unregister_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to unregister ++ * name : ACPI Thermal zone name like TZ00 ++ */ ++int thermal_unregister_sensor(const char* name); ++ ++2 Sensor driver callbacks ++======================= ++ ++The sensor driver needs to implement the following callbacks as defined ++in struct thermal_sensor_ops ++ ++struct thermal_sensor_ops{ ++ thermal_sensor_set_aux_trip setauxtrip; //Get current AUX trip ++ thermal_sensor_get_aux_trip getauxtrip; //Set new AUX trip ++ thermal_sensor_get_temp_base gettempbase; //Get temperature base (K/c) ++ thermal_sensor_get_caps getcaps; //Get sensor capabilities ++}; ++ ++2.1 Get AUX trip ++ ++/* ++ * sensor_get_auxtrip ++ * ----------------- ++ * get the current auxtrip value from sensor throughec ++ * name: Thermalzone name ++ * auxtype : AUX0/AUX1 ++ * buf: syfs buffer ++ */ ++int sensor_get_auxtrip(const char* name,const int auxtype, char* buf) ++ ++2.2 Set AUX trip ++ ++/* ++ * sensor_set_auxtrip ++ * ----------------- ++ * set the new auxtrip value to sensor through ec ++ * name: Thermalzone name ++ * auxtype : AUX0/AUX1 ++ * buf: syfs buffer ++ */ ++int sensor_set_auxtrip(const char* name,const int auxtype,const char* buf) ++ ++2.3 Get Capabilities ++ ++/* ++ * sensor_get_caps ++ * ----------------- ++ * get the capabilities of sensor ++ * name: Thermalzone name ++ * buf: syfs buffer ++ */ ++int sensor_get_caps(const char* name, char* buf) ++ ++2.4 Get temperature base ++ ++/* ++ * sensor_get_tempbase ++ * ----------------- ++ * get the temperature base (Kelvin /Celsius) ++ * name: Thermalzone name ++ * buf: syfs buffer ++ */ ++int sensor_get_tempbase(const char* name, char* buf) ++ +diff --git a/Documentation/thermal/thermal-extensions.txt b/Documentation/thermal/thermal-extensions.txt +new file mode 100644 +index 0000000..c121a48 +--- /dev/null ++++ b/Documentation/thermal/thermal-extensions.txt +@@ -0,0 +1,151 @@ ++The thermal extensions ++====================== ++ ++Written by Sujith Thomas ++ ++Updated: 30 July 2007 ++ ++Copyright (c) 2007 Intel Corporation ++ ++ ++0. Introduction ++ ++The current thermal management solution in Linux is strictly ++kernel based and supports only CPU class of devices. The "thermal extensions " ++is a framework for supporting user-space thermal management solutions. ++The framework depends on a stack of components rangng from embedded ++controller's firmware, BIOS, kernel and application. This document will ++be focussing on the the kernel layer. ++ ------------- ++ | syfs | ++ ------------- ++ -------------------------------------------------------------- ++ | ++ | ------------ ++ | ---------| CPU | ++ | | ------------ ++ | | ++ | | ------------ ++ | | -----| LCD | ++ | | | ------------ ++ | | | ++ --------------- | | | ------------- ++ |Sensor driver|--------- | | | --| WLAN | ++ --------------- | | | | | ------------- ++ | | | | | ........... ++ | | | | | ........... ++ --------------------- ++ | Thermal zone | ++ --------------------- ++ | ++ | ++ ------- ++ | BIOS| ++ ------- ++ ++The modifications done for thermal zone driver strictly falls under ++ACPI 2.0 specification. The "thermal extensions" basicallly accepts ++registration from devices those are thermal contributors and exposes ++the throttle mechanism to the user-space applications via sysfs. ++Similarly there is a platform sensor driver that registers with the ++thermal zone driver providing mechanism for programming AUX trip points. ++ ++ ++1. Sysfs directory structure ++ ++The sysfs entry will be made under /sys/thermal and it will have the ++following group of attributes. ++ ++-/sys/thermal/config (thermal management related configuration) ++-/sys/thermal/ (thermal zone related data) ++-/sys/thermal// (info about a device in a thermal zone) ++ ++1.1 /sys/thermal/config ++ ++This folder has the following attributes ++ ++-mode (0 = user-space thermal managemnt ; 1= kernel-space thermal management) ++-userenabled (0 if kernel is not willing to give control to application else 1) ++ ++ ++1.2 /sys/thermal/ ++ ++The below attributes will appear for any thermal zone ++ ++-critical (_CRT as reported by BIOS) ++-hot (_HOT as reported by BIOS) ++-passive (_PSV as reported by BIOS) ++-temperature (_TMP as reported by BIOS) ++ ++The below attributes will appear only if platform sensor driver is loaded. ++ ++-aux0 (lower AUX value interface for platform sensor driver) ++-aux1 (upper AUX value interface for platform sensor driver) ++-sensorcapabilities (capabilities as defined in thermal.h) ++-tempbase (The way temperature is reported K/celsius) ++-sensorclass (The class of sensor as in SKIN or CPU or ...) ++ ++1.3 /sys/thermal// ++ ++The below attributes will appear for each and every device registered ++with thermal zone driver and that has an entrly in _TZD. ++ ++-maxthrottlestate (maximum no:of states supported by this device) ++-deviceclass (as defined in thermal.h) ++-capabilities (as defined in thermal.h) ++-throttletype (Absolute/Relative ) ++-throttlestate ++(if throttletype == Absolute -> current/new state of the device for eg: P1-T3 for CPU ++ Lower 16 bits is the P-state and higher 16 bits are T-state ++ if throttletype == Relative -> this field will take the next step level for throttling as input) ++ ++ ++2. Modified file list ++ ++2.1 include/linux/thermal.h ++ ++-All the definitions are moved from "thermal.c"into new file "thermal.h" ++ ++2.2 drivers/acpi/thermal.c ++ ++-Support for user-space thermal management algorithm ++-Replaced procfs with sysfs ++-Removed the dependency of the thermal driver on acpi_processor driver ++ ++2.3 drivers/acpi/thermal_sensor.c ++-Support for programming AUX trip points in platform sensors ++-Support for disabling user-space thermal management ++ ++2.4 drivers/acpi/processor_core.c ++-Registers with thermal zone driver as a participant device ++-Provides support for both P & T state throttling ++ ++2.5 drivers/acpi/video.c ++-Registers with thermal zone driver as a participant device ++-Provides support for backlight controlling of LCD ++ ++2.6 drivers/acpi/smi_thermal.c ++-Generic driver for providing thermal controls to all devices which use ++SMI for device throttling ++ ++2.7 include/linux/smi_thermal.h ++-Generic driver for providing thermal controls to all devices which use ++SMI for device throttling. Struct definition. ++ ++2.8 drivers/acpi/smi_device_throttle.c ++-Platform specific driver for throttling devices based on SMI mechanism. ++ ++2.9 drivers/acpi/Kconfig ++-Added support for conditional build with "thermal extensions" ++ ++2.10 drivers/acpi/Makefile ++ ++2.11 drivers/cpufreq/cpufreq.c ++-Brought back the cpufreq_set_policy interface. ++ ++2.12 include/linux/cpufreq.h ++-Brought back the cpufreq_set_policy interface. ++ ++2.13 include/acpi/processor.h ++-change in acpi_processor structure ++ +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index a9826f2..3c74305 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -122,17 +122,6 @@ config ACPI_BUTTON + such as shutting down the system. This is necessary for + software controlled poweroff. + +-config ACPI_VIDEO +- tristate "Video" +- depends on X86 && BACKLIGHT_CLASS_DEVICE +- help +- This driver implement the ACPI Extensions For Display Adapters +- for integrated graphics devices on motherboard, as specified in +- ACPI 2.0 Specification, Appendix B, allowing to perform some basic +- control like defining the video POST device, retrieving EDID information +- or to setup a video output, etc. +- Note that this is an ref. implementation only. It may or may not work +- for your integrated video device. + + config ACPI_FAN + tristate "Fan" +@@ -155,6 +144,28 @@ config ACPI_BAY + This driver adds support for ACPI controlled removable drive + bays such as the IBM ultrabay or the Dell Module Bay. + ++config ACPI_THERMAL ++ tristate "Thermal Zone" ++ default y ++ help ++ This driver adds support for ACPI thermal zones. Most mobile and ++ some desktop systems support ACPI thermal zones. It is HIGHLY ++ recommended that this option be enabled, as your processor(s) ++ may be damaged without it. ++ ++config ACPI_VIDEO ++ tristate "Video" ++ depends on X86 && BACKLIGHT_CLASS_DEVICE ++ default n ++ help ++ This driver implement the ACPI Extensions For Display Adapters ++ for integrated graphics devices on motherboard, as specified in ++ ACPI 2.0 Specification, Appendix B, allowing to perform some basic ++ control like defining the video POST device, retrieving EDID information ++ or to setup a video output, etc. ++ Note that this is an ref. implementation only. It may or may not work ++ for your integrated video device. ++ + config ACPI_PROCESSOR + tristate "Processor" + default y +@@ -170,15 +181,6 @@ config ACPI_HOTPLUG_CPU + select ACPI_CONTAINER + default y + +-config ACPI_THERMAL +- tristate "Thermal Zone" +- depends on ACPI_PROCESSOR +- default y +- help +- This driver adds support for ACPI thermal zones. Most mobile and +- some desktop systems support ACPI thermal zones. It is HIGHLY +- recommended that this option be enabled, as your processor(s) +- may be damaged without it. + + config ACPI_NUMA + bool "NUMA support" +diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c +index 88a6fc7..30b8ded 100644 +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -1,9 +1,11 @@ + /* +- * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) ++ * thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh +- * ++ * Copyright (C) 2006, 2007 Sujith Thomas ++ * Copyright (C) 2006, 2007 Manohar P ++ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify +@@ -28,13 +30,12 @@ + * TBD: 1. Implement passive cooling hysteresis. + * 2. Enhance passive cooling (CPU) states/limit interface to support + * concepts of 'multiple limiters', upper/lower limits, etc. ++ * Modified: 1. Provide infrastructure from kernel to enable user-space ++ * thermal management algorithm + * + */ + +-#include +-#include +-#include +-#include ++#include + #include + #include + #include +@@ -42,31 +43,6 @@ + #include + #include + +-#include +-#include +- +-#define ACPI_THERMAL_COMPONENT 0x04000000 +-#define ACPI_THERMAL_CLASS "thermal_zone" +-#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" +-#define ACPI_THERMAL_FILE_STATE "state" +-#define ACPI_THERMAL_FILE_TEMPERATURE "temperature" +-#define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" +-#define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" +-#define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" +-#define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 +-#define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 +-#define ACPI_THERMAL_NOTIFY_DEVICES 0x82 +-#define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 +-#define ACPI_THERMAL_NOTIFY_HOT 0xF1 +-#define ACPI_THERMAL_MODE_ACTIVE 0x00 +-#define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" +- +-#define ACPI_THERMAL_MAX_ACTIVE 10 +-#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 +- +-#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10) +-#define CELSIUS_TO_KELVIN(t) ((t+273)*10) +- + #define _COMPONENT ACPI_THERMAL_COMPONENT + ACPI_MODULE_NAME("thermal"); + +@@ -78,6 +54,14 @@ static int tzp; + module_param(tzp, int, 0); + MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); + ++static void acpi_thermal_enumerate(struct acpi_thermal *tz); ++static void acpi_thermal_reenumerate(struct acpi_thermal *tz); ++static int acpi_thermal_verify_td_in_tz(struct acpi_thermal *tz, ++ struct thermal_device *td, ++ enum action_type action); ++static void acpi_thermal_add_td_info(struct kobject *kobj, ++ struct thermal_device_info *info); ++ + static int acpi_thermal_add(struct acpi_device *device); + static int acpi_thermal_remove(struct acpi_device *device, int type); + static int acpi_thermal_resume(struct acpi_device *device); +@@ -103,73 +87,6 @@ static struct acpi_driver acpi_thermal_driver = { + }, + }; + +-struct acpi_thermal_state { +- u8 critical:1; +- u8 hot:1; +- u8 passive:1; +- u8 active:1; +- u8 reserved:4; +- int active_index; +-}; +- +-struct acpi_thermal_state_flags { +- u8 valid:1; +- u8 enabled:1; +- u8 reserved:6; +-}; +- +-struct acpi_thermal_critical { +- struct acpi_thermal_state_flags flags; +- unsigned long temperature; +-}; +- +-struct acpi_thermal_hot { +- struct acpi_thermal_state_flags flags; +- unsigned long temperature; +-}; +- +-struct acpi_thermal_passive { +- struct acpi_thermal_state_flags flags; +- unsigned long temperature; +- unsigned long tc1; +- unsigned long tc2; +- unsigned long tsp; +- struct acpi_handle_list devices; +-}; +- +-struct acpi_thermal_active { +- struct acpi_thermal_state_flags flags; +- unsigned long temperature; +- struct acpi_handle_list devices; +-}; +- +-struct acpi_thermal_trips { +- struct acpi_thermal_critical critical; +- struct acpi_thermal_hot hot; +- struct acpi_thermal_passive passive; +- struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; +-}; +- +-struct acpi_thermal_flags { +- u8 cooling_mode:1; /* _SCP */ +- u8 devices:1; /* _TZD */ +- u8 reserved:6; +-}; +- +-struct acpi_thermal { +- struct acpi_device * device; +- acpi_bus_id name; +- unsigned long temperature; +- unsigned long last_temperature; +- unsigned long polling_frequency; +- volatile u8 zombie; +- struct acpi_thermal_flags flags; +- struct acpi_thermal_state state; +- struct acpi_thermal_trips trips; +- struct acpi_handle_list devices; +- struct timer_list timer; +-}; +- + static const struct file_operations acpi_thermal_state_fops = { + .open = acpi_thermal_state_open_fs, + .read = seq_read, +@@ -207,6 +124,35 @@ static const struct file_operations acpi_thermal_polling_fops = { + .release = single_release, + }; + ++static char *thermal_mode[THERMAL_MAX_MODE] = { ++ "user", ++ "kernel", ++}; ++ ++static char *thermal_throttle_type[THERMAL_MAX_THROTTLE_TYPE] = { ++ "absolute", ++ "relative", ++}; ++ ++static struct thermal_config thermalconfig = { ++ .userenabled = THERMAL_USER_ENABLED, ++ .mode = THERMAL_KERNELSPACE, ++}; ++ ++/*Linked list of thermal zones*/ ++static LIST_HEAD(acpi_thermal_list); ++/*Linked list of registered component drivers*/ ++static LIST_HEAD(thermal_device_driver_list); ++/*Linked list of registered components*/ ++static LIST_HEAD(registered_thermal_device_list); ++ ++/*Lock for accessing thermalzone linked list*/ ++DEFINE_SPINLOCK(tz_list_lock); ++/*Lock for accessing device driver linked list*/ ++DEFINE_SPINLOCK(dd_list_lock); ++/*Lock for accessing thermal device linked list*/ ++DEFINE_SPINLOCK(td_list_lock); ++ + /* -------------------------------------------------------------------------- + Thermal Zone Management + -------------------------------------------------------------------------- */ +@@ -480,6 +426,46 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) + return 0; + } + ++/* ++ * acpi_set_passive_thermal_limit ++ * ----------------------------- ++ * Interface function for passive devices like CPU to throttle ++ * name : handle to ACPI devices like CPU0 ++ * step : device will be put into current throttle level + step ++ */ ++ ++int acpi_set_passive_thermal_limit(acpi_handle handle, int step) ++{ ++ int result; ++ struct acpi_device *ad; ++ char buf[3]; /*-10 MAX_THROTTLE_STEP) ++ return -EINVAL; ++ ++ sprintf(buf, "%d", step); ++ ++ result = acpi_bus_get_device(handle, &ad); ++ spin_lock(&td_list_lock); ++ list_for_each(entry_td, ®istered_thermal_device_list) { ++ td = list_entry(entry_td, struct thermal_device, node); ++ if (td->info.name == ad->pnp.bus_id) { ++ if (td->info.dd && td->info.dd->ops->setthrottlelimit) { ++ result = ++ td->info.dd->ops-> ++ setthrottlelimit(THROTTLE_REL, ++ td->info.private, buf); ++ } ++ spin_unlock(&td_list_lock); ++ return result; ++ } ++ } ++ spin_unlock(&td_list_lock); ++ return -ENODEV; ++} ++ + static void acpi_thermal_passive(struct acpi_thermal *tz) + { + int result = 1; +@@ -513,10 +499,11 @@ static void acpi_thermal_passive(struct acpi_thermal *tz) + /* Heating up? */ + if (trend > 0) + for (i = 0; i < passive->devices.count; i++) +- acpi_processor_set_thermal_limit(passive-> +- devices. +- handles[i], +- ACPI_PROCESSOR_LIMIT_INCREMENT); ++ acpi_set_passive_thermal_limit(passive-> ++ devices. ++ handles[i], ++ THROTTLE_INCREMENT_STEP); ++ + /* Cooling off? */ + else if (trend < 0) { + for (i = 0; i < passive->devices.count; i++) +@@ -525,10 +512,11 @@ static void acpi_thermal_passive(struct acpi_thermal *tz) + * freq/lowest thrott and can leave + * passive mode, even in error case + */ +- if (!acpi_processor_set_thermal_limit ++ if (!acpi_set_passive_thermal_limit + (passive->devices.handles[i], +- ACPI_PROCESSOR_LIMIT_DECREMENT)) ++ THROTTLE_DECREMENT_STEP)) + result = 0; ++ + /* + * Leave cooling mode, even if the temp might + * higher than trip point This is because some +@@ -556,10 +544,10 @@ static void acpi_thermal_passive(struct acpi_thermal *tz) + if (!passive->flags.enabled) + return; + for (i = 0; i < passive->devices.count; i++) +- if (!acpi_processor_set_thermal_limit +- (passive->devices.handles[i], +- ACPI_PROCESSOR_LIMIT_DECREMENT)) ++ if (!acpi_set_passive_thermal_limit ++ (passive->devices.handles[i], THROTTLE_DECREMENT_STEP)) + result = 0; ++ + if (result) { + passive->flags.enabled = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, +@@ -662,6 +650,19 @@ static void acpi_thermal_check(void *data) + return; + } + ++ /* ++ * Check for user/kernel algo ++ * ------------------------- ++ *If there is a thermal management application in userspace ++ *Or there are non CPU devices in this thermal zone ++ *Kernelspace solution won't handle this ++ */ ++ ++ if (THERMAL_KERNELSPACE != thermalconfig.mode ++ || THERMAL_CPU_CLASS != tz->class) { ++ return; ++ } ++ + state = tz->state; + + result = acpi_thermal_get_temperature(tz); +@@ -1094,7 +1095,687 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) + } + + /* -------------------------------------------------------------------------- +- Driver Interface ++ Attribute implementation functions - TZ ++----------------------------------------------------------------------------- */ ++ ++static ssize_t aux0_show(struct acpi_thermal *tz, char *buf) ++{ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->getauxtrip) { ++ tz->ops->getauxtrip(tz->name, THERMAL_AUX0, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t aux0_store(struct acpi_thermal *tz, const char *buf, ++ size_t count) ++{ ++ int data; ++ if (!tz || !buf || THERMAL_USERSPACE != thermalconfig.mode) ++ return -EINVAL; ++ ++ /*Sanity check; should be integer*/ ++ if (!sscanf(buf, "%d", &data)) ++ return -EINVAL; ++ ++ /*Sanity check ( 0trips.critical.flags.valid ++ && data > ++ KELVIN_TO_CELSIUS(tz->trips.critical.temperature))) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->setauxtrip) { ++ tz->ops->setauxtrip(tz->name, THERMAL_AUX0, buf); ++ } ++ ++ return count; ++} ++ ++static ssize_t aux1_show(struct acpi_thermal *tz, char *buf) ++{ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->getauxtrip) { ++ tz->ops->getauxtrip(tz->name, THERMAL_AUX1, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t aux1_store(struct acpi_thermal *tz, const char *buf, ++ size_t count) ++{ ++ int data; ++ if (!tz || !buf || THERMAL_USERSPACE != thermalconfig.mode) ++ return -EINVAL; ++ ++ /*Sanity check; should be integer*/ ++ if (!sscanf(buf, "%d", &data)) ++ return -EINVAL; ++ ++ /*Sanity check ( 0trips.critical.flags.valid ++ && data > ++ KELVIN_TO_CELSIUS(tz->trips.critical.temperature))) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->setauxtrip) { ++ tz->ops->setauxtrip(tz->name, THERMAL_AUX1, buf); ++ } ++ ++ return count; ++} ++ ++static ssize_t sensorcapabilities_show(struct acpi_thermal *tz, char *buf) ++{ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->getcaps) { ++ tz->ops->getcaps(tz->name, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t tempbase_show(struct acpi_thermal *tz, char *buf) ++{ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->ops && tz->ops->gettempbase) { ++ tz->ops->gettempbase(tz->name, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t sensorclass_show(struct acpi_thermal *tz, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ s += sprintf(s, "%d \n", tz->class); ++ ++ return (s - buf); ++} ++ ++static ssize_t critical_show(struct acpi_thermal *tz, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->trips.critical.flags.valid) ++ s += sprintf(s, "%ld \n", ++ KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); ++ ++ return (s - buf); ++} ++ ++static ssize_t hot_show(struct acpi_thermal *tz, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->trips.hot.flags.valid) ++ s += sprintf(s, "%ld \n", ++ KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); ++ ++ return (s - buf); ++} ++ ++static ssize_t passive_show(struct acpi_thermal *tz, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ if (tz->trips.passive.flags.valid) ++ s += sprintf(s, "%ld ", ++ KELVIN_TO_CELSIUS(tz->trips.passive.temperature)); ++ ++ return (s - buf); ++} ++ ++static ssize_t temperature_show(struct acpi_thermal *tz, char *buf) ++{ ++ char *s = buf; ++ ACPI_FUNCTION_TRACE("temp_show"); ++ ++ if (!tz || !buf) ++ return -EINVAL; ++ ++ acpi_thermal_get_temperature(tz); ++ ++ s += sprintf(s, "%lu \n", KELVIN_TO_CELSIUS(tz->temperature)); ++ ++ return (s - buf); ++ ++} ++ ++/* -------------------------------------------------------------------------- ++ sysfs Interface - TZ ++----------------------------------------------------------------------------- */ ++ ++/*Call back function prototypes*/ ++struct thermalzone_attribute { ++ struct attribute attr; ++ ssize_t(*show) (struct acpi_thermal *tz, char *buf); ++ ssize_t(*store) (struct acpi_thermal *tz, const char *buf, ++ size_t count); ++}; ++ ++/*Helper macros for using THERMALZONE attributes*/ ++#define THERMALZONE_ATTR(_name, _mode, _show, _store) \ ++struct thermalzone_attribute thermalzone_attr_##_name = { \ ++ .attr = { \ ++ .name = __stringify(_name), \ ++ .mode = _mode, \ ++ .owner = THIS_MODULE, \ ++ }, \ ++ .show = _show, \ ++ .store = _store, \ ++}; ++ ++#define to_thermalzone_attr(_attr) \ ++ (container_of(_attr, \ ++ struct thermalzone_attribute, \ ++ attr)) ++ ++#define to_acpi_thermal(obj) \ ++ container_of(obj, struct acpi_thermal, kobj) ++ ++/*Attribute list for THERMALZONE subsystem*/ ++ ++/*current AUX0 trip value*/ ++static THERMALZONE_ATTR(aux0, 0644, aux0_show, aux0_store); ++/*current AUX1 trip value*/ ++static THERMALZONE_ATTR(aux1, 0644, aux1_show, aux1_store); ++static THERMALZONE_ATTR(sensorcapabilities, 0444, ++ sensorcapabilities_show, NULL); ++/*Kelvin or Celsius*/ ++static THERMALZONE_ATTR(tempbase, 0444, tempbase_show, NULL); ++/*enum participant_class*/ ++static THERMALZONE_ATTR(sensorclass, 0444, sensorclass_show, NULL); ++ ++static struct thermalzone_attribute *thermalzone_extn_attrs[] = { ++ &thermalzone_attr_aux0, ++ &thermalzone_attr_aux1, ++ &thermalzone_attr_sensorcapabilities, ++ &thermalzone_attr_tempbase, ++ &thermalzone_attr_sensorclass, ++ NULL, ++}; ++ ++/*_CRT*/ ++static THERMALZONE_ATTR(critical, 0444, critical_show, NULL); ++/*_HOT*/ ++static THERMALZONE_ATTR(hot, 0444, hot_show, NULL); ++/*_PSV*/ ++static THERMALZONE_ATTR(passive, 0444, passive_show, NULL); ++/*current temperature*/ ++static THERMALZONE_ATTR(temperature, 0444, temperature_show, NULL); ++ ++static struct thermalzone_attribute *thermalzone_attrs[] = { ++ &thermalzone_attr_critical, ++ &thermalzone_attr_hot, ++ &thermalzone_attr_passive, ++ &thermalzone_attr_temperature, ++ NULL, ++}; ++ ++static struct attribute *def_attrs[] = { ++ NULL, ++}; ++ ++/*Populate the attributes of thermalzone kobject*/ ++static void thermalzone_populate_dir(struct acpi_thermal *tz) ++{ ++ struct thermalzone_attribute *attr; ++ int error = 0; ++ int i; ++ ++ for (i = 0; (attr = thermalzone_attrs[i]) && !error; i++) { ++ error = sysfs_create_file(&tz->kobj, &attr->attr); ++ } ++} ++ ++/*Add the sensor driver specific inf*/ ++static void thermalzone_sensorinfo_populate_dir(struct acpi_thermal *tz) ++{ ++ struct thermalzone_attribute *attr; ++ int error = 0; ++ int i; ++ ++ for (i = 0; (attr = thermalzone_extn_attrs[i]) && !error; i++) { ++ error = sysfs_create_file(&tz->kobj, &attr->attr); ++ } ++} ++ ++/*Remove the sensor driver specific info*/ ++static void thermalzone_sensorinfo_unpopulate_dir(struct acpi_thermal *tz) ++{ ++ struct thermalzone_attribute *attr; ++ int i; ++ ++ for (i = 0; (attr = thermalzone_extn_attrs[i]); i++) { ++ sysfs_remove_file(&tz->kobj, &attr->attr); ++ } ++} ++ ++/*kobj_type callback function for 'show'*/ ++static ssize_t ++thermalzone_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) ++{ ++ struct acpi_thermal *tzone = to_acpi_thermal(kobj); ++ struct thermalzone_attribute *thermalzone_attr = ++ to_thermalzone_attr(attr); ++ ssize_t ret = -EIO; ++ ++ /*Call attribute callback function*/ ++ if (thermalzone_attr->show) ++ ret = thermalzone_attr->show(tzone, buf); ++ ++ return ret; ++ ++} ++ ++/*kobj_type callback function for 'store'*/ ++static ssize_t ++thermalzone_attr_store(struct kobject *kobj, struct attribute *attr, ++ const char *buf, size_t len) ++{ ++ struct acpi_thermal *tzone = to_acpi_thermal(kobj); ++ struct thermalzone_attribute *thermalzone_attr = ++ to_thermalzone_attr(attr); ++ ++ ssize_t ret = -EIO; ++ ++ /*Call attribute callback function*/ ++ if (thermalzone_attr->store) ++ ret = thermalzone_attr->store(tzone, buf, len); ++ return ret; ++} ++ ++/*Call back registration for thermalzone*/ ++static struct sysfs_ops thermalzone_attr_ops = { ++ .show = thermalzone_attr_show, ++ .store = thermalzone_attr_store, ++}; ++ ++/*ktype for thermalzone*/ ++static struct kobj_type ktype_thermalzone = { ++ .sysfs_ops = &thermalzone_attr_ops, ++ .default_attrs = def_attrs, ++}; ++ ++static decl_subsys(thermal, &ktype_thermalzone, NULL); ++ ++/* -------------------------------------------------------------------------- ++ Attribute implementation functions - Thermal config ++----------------------------------------------------------------------------- */ ++static ssize_t userenabled_show(struct thermal_config *tc, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tc || !buf) ++ return -EINVAL; ++ ++ s += sprintf(s, "%d \n", tc->userenabled); ++ ++ return (s - buf); ++} ++ ++static ssize_t mode_show(struct thermal_config *tc, char *buf) ++{ ++ char *s = buf; ++ ++ if (!tc || !buf) ++ return -EINVAL; ++ ++ s += sprintf(s, "%s \n", thermal_mode[tc->mode]); ++ ++ return (s - buf); ++} ++ ++static ssize_t mode_store(struct thermal_config *tc, const char *buf, ++ size_t count) ++{ ++ int i; ++ if (!tc || !buf) ++ return -EINVAL; ++ ++ if (THERMAL_USER_ENABLED == thermalconfig.userenabled) { ++ for (i = 0; i < THERMAL_MAX_MODE; i++) { ++ if (!strncmp ++ (thermal_mode[i], buf, strlen(thermal_mode[i]))) ++ tc->mode = i; ++ } ++ } ++ ++ return count; ++} ++ ++/* -------------------------------------------------------------------------- ++ sysfs Interface - config ++----------------------------------------------------------------------------- */ ++ ++/*Call back function prototypes*/ ++struct thermalconfig_attribute { ++ struct attribute attr; ++ ssize_t(*show) (struct thermal_config *tc, char *buf); ++ ssize_t(*store) (struct thermal_config *tc, const char *buf, ++ size_t count); ++}; ++ ++/*Helper macros for using THERMALCONFIG attributes*/ ++#define THERMALCONFIG_ATTR(_name, _mode, _show, _store) \ ++struct thermalconfig_attribute thermalconfig_attr_##_name = { \ ++ .attr = { \ ++ .name = __stringify(_name), \ ++ .mode = _mode, \ ++ .owner = THIS_MODULE \ ++ }, \ ++ .show = _show, \ ++ .store = _store, \ ++}; ++ ++#define to_thermalconfig_attr(_attr) \ ++ (container_of(_attr, \ ++ struct thermalconfig_attribute, \ ++ attr)) ++ ++#define to_thermal_config(obj) \ ++ container_of(obj, struct thermal_config, kobj) ++ ++/*kobj_type callback function for 'show'*/ ++static ssize_t ++thermalconfig_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) ++{ ++ struct thermal_config *tc = to_thermal_config(kobj); ++ struct thermalconfig_attribute *thermalconfig_attr = ++ to_thermalconfig_attr(attr); ++ ssize_t ret = -EIO; ++ ++ if (thermalconfig_attr->show) ++ ret = thermalconfig_attr->show(tc, buf); ++ ++ return ret; ++} ++ ++/*kobj_type callback function for 'store'*/ ++static ssize_t ++thermalconfig_attr_store(struct kobject *kobj, struct attribute *attr, ++ const char *buf, size_t len) ++{ ++ struct thermal_config *tc = to_thermal_config(kobj); ++ struct thermalconfig_attribute *thermalconfig_attr = ++ to_thermalconfig_attr(attr); ++ ++ ssize_t ret = -EIO; ++ ++ if (thermalconfig_attr->store) ++ ret = thermalconfig_attr->store(tc, buf, len); ++ ++ return ret; ++} ++ ++/*Enable/Disable userspace algo*/ ++static THERMALCONFIG_ATTR(userenabled, 0444, userenabled_show, NULL); ++/*Kernel/user algo in execution*/ ++static THERMALCONFIG_ATTR(mode, 0644, mode_show, mode_store); ++ ++static struct thermalconfig_attribute *thermalconfig_attrs[] = { ++ &thermalconfig_attr_userenabled, ++ &thermalconfig_attr_mode, ++ NULL, ++}; ++ ++/*Populate the attributes of thermalconfig kobject*/ ++static void thermalconfig_populate_dir(struct thermal_config *tc) ++{ ++ struct thermalconfig_attribute *attr; ++ int error = 0; ++ int i; ++ ++ for (i = 0; (attr = thermalconfig_attrs[i]) && !error; i++) { ++ error = sysfs_create_file(&tc->kobj, &attr->attr); ++ } ++} ++ ++/*Call back registration for thermalzone*/ ++static struct sysfs_ops thermalconfig_attr_ops = { ++ .show = thermalconfig_attr_show, ++ .store = thermalconfig_attr_store, ++}; ++ ++/*ktype for thermaconfig*/ ++static struct kobj_type ktype_thermalconfig = { ++ .sysfs_ops = &thermalconfig_attr_ops, ++ .default_attrs = def_attrs, ++}; ++ ++/* -------------------------------------------------------------------------- ++ Attribute implementation functions - devices ++----------------------------------------------------------------------------- */ ++static ssize_t throttlestate_show(struct thermal_device_info *info, char *buf) ++{ ++ if (!info || !buf) ++ return -EINVAL; ++ ++ if (info->dd && info->dd->ops->getthrottlelimit) { ++ info->dd->ops->getthrottlelimit(info->private, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t throttlestate_store(struct thermal_device_info *info, ++ const char *buf, size_t count) ++{ ++ int data; ++ ++ if (!info || !buf || THERMAL_USERSPACE != thermalconfig.mode) ++ return -EINVAL; ++ ++ /*Sanity check; should be integer*/ ++ if (!sscanf(buf, "%d", &data)) ++ return -EINVAL; ++ ++ if (info->dd && info->dd->ops->setthrottlelimit) { ++ info->dd->ops->setthrottlelimit(info->common->type, ++ info->private, buf); ++ } ++ ++ return count; ++} ++ ++static ssize_t throttletype_show(struct thermal_device_info *info, char *buf) ++{ ++ int throttletype; ++ char *s = buf; ++ if (!info || !buf) ++ return -EINVAL; ++ ++ throttletype = info->common->type; ++ s += sprintf(s, "%s \n", thermal_throttle_type[throttletype]); ++ ++ return (s - buf); ++} ++ ++static ssize_t throttletype_store(struct thermal_device_info *info, ++ const char *buf, size_t count) ++{ ++ int i; ++ if (!info || !buf || THERMAL_USERSPACE != thermalconfig.mode) ++ return -EINVAL; ++ ++ for (i = 0; i < THERMAL_MAX_THROTTLE_TYPE; i++) { ++ if (!strncmp ++ (thermal_throttle_type[i], buf, ++ strlen(thermal_throttle_type[i]))) ++ info->common->type = i; ++ } ++ ++ return count; ++} ++ ++static ssize_t maxthrottlestate_show(struct thermal_device_info *info, ++ char *buf) ++{ ++ if (!info || !buf) ++ return -EINVAL; ++ ++ if (info->dd && info->dd->ops->getmaxthrottlelimit) { ++ info->dd->ops->getmaxthrottlelimit(info->private, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++static ssize_t deviceclass_show(struct thermal_device_info *info, char *buf) ++{ ++ char *s = buf; ++ ++ if (!info || !buf) ++ return -EINVAL; ++ ++ s += sprintf(s, "%lu\n", info->dd->class); ++ ++ return (s - buf); ++} ++ ++static ssize_t capabilities_show(struct thermal_device_info *info, char *buf) ++{ ++ if (!info || !buf) ++ return -EINVAL; ++ ++ if (info->dd && info->dd->ops->getcaps) { ++ info->dd->ops->getcaps(info->private, buf); ++ } ++ ++ return strlen(buf); ++} ++ ++/* -------------------------------------------------------------------------- ++ sysfs Interface - devices ++----------------------------------------------------------------------------- */ ++ ++/*Call back function prototypes*/ ++struct devices_attribute { ++ struct attribute attr; ++ ssize_t(*show) (struct thermal_device_info *info, char *buf); ++ ssize_t(*store) (struct thermal_device_info *info, const char *buf, ++ size_t count); ++}; ++ ++/*Helper macros for using devices attributes*/ ++#define DEVICES_ATTR(_name, _mode, _show, _store) \ ++struct devices_attribute devices_attr_##_name = { \ ++ .attr = { \ ++ .name = __stringify(_name), \ ++ .mode = _mode, \ ++ .owner = THIS_MODULE \ ++ }, \ ++ .show = _show, \ ++ .store = _store, \ ++}; ++ ++#define to_devices_attr(_attr) \ ++ container_of(_attr, struct devices_attribute, attr) ++#define to_thermal_device_info(obj) \ ++ container_of(obj, struct thermal_device_info, kobj) ++ ++/*kobj_type callback function for 'show'*/ ++static ssize_t ++devices_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) ++{ ++ struct thermal_device_info *info = to_thermal_device_info(kobj); ++ ++ struct devices_attribute *devices_attr = to_devices_attr(attr); ++ ssize_t ret = -EIO; ++ ++ if (devices_attr->show) ++ ret = devices_attr->show(info, buf); ++ ++ return ret; ++} ++ ++/*kobj_type callback function for 'store'*/ ++static ssize_t ++devices_attr_store(struct kobject *kobj, struct attribute *attr, ++ const char *buf, size_t len) ++{ ++ struct thermal_device_info *info = to_thermal_device_info(kobj); ++ struct devices_attribute *devices_attr = to_devices_attr(attr); ++ ++ ssize_t ret = -EIO; ++ ++ if (devices_attr->store) ++ ret = devices_attr->store(info, buf, len); ++ ++ return ret; ++} ++ ++/*Current state/newStep or State*/ ++static DEVICES_ATTR(throttlestate, 0644, ++ throttlestate_show, throttlestate_store); ++/*Absolute/Relative*/ ++static DEVICES_ATTR(throttletype, 0644, throttletype_show, throttletype_store); ++/*max state supported*/ ++static DEVICES_ATTR(maxthrottlestate, 0444, maxthrottlestate_show, NULL); ++/*enum participant_class*/ ++static DEVICES_ATTR(deviceclass, 0444, deviceclass_show, NULL); ++/*device capabilities*/ ++static DEVICES_ATTR(capabilities, 044, capabilities_show, NULL); ++ ++static struct devices_attribute *devices_attrs[] = { ++ &devices_attr_throttlestate, ++ &devices_attr_throttletype, ++ &devices_attr_maxthrottlestate, ++ &devices_attr_deviceclass, ++ &devices_attr_capabilities, ++ NULL, ++}; ++ ++/*Call back registration for thermalzone*/ ++static struct sysfs_ops devices_attr_ops = { ++ .show = devices_attr_show, ++ .store = devices_attr_store, ++}; ++ ++/*ktype for devices*/ ++static struct kobj_type ktype_devices = { ++ .sysfs_ops = &devices_attr_ops, ++ .default_attrs = def_attrs, ++}; ++ ++/*Populate the attributes of thermalconfig kobject*/ ++static void devices_populate_dir(struct thermal_device_info *info) ++{ ++ struct devices_attribute *attr; ++ ++ int error = 0; ++ int i; ++ ++ for (i = 0; (attr = devices_attrs[i]) && !error; i++) { ++ error = sysfs_create_file(&info->kobj, &attr->attr); ++ } ++} ++ ++/* -------------------------------------------------------------------------- ++ Driver Interface + -------------------------------------------------------------------------- */ + + static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) +@@ -1110,16 +1791,28 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) + + switch (event) { + case ACPI_THERMAL_NOTIFY_TEMPERATURE: ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Received an event from TZ: %s event type:%x \n", ++ tz->name, event)); ++ /*kernel space algorithm*/ + acpi_thermal_check(tz); ++ /*Event for user space algorithm*/ ++ if (THERMAL_USERSPACE == thermalconfig.mode) ++ kobject_uevent(&tz->kobj, KOBJ_CHANGE); + break; + case ACPI_THERMAL_NOTIFY_THRESHOLDS: + acpi_thermal_get_trip_points(tz); + acpi_thermal_check(tz); ++ if (THERMAL_USERSPACE == thermalconfig.mode) ++ kobject_uevent(&tz->kobj, KOBJ_MOVE); + acpi_bus_generate_event(device, event, 0); + break; + case ACPI_THERMAL_NOTIFY_DEVICES: + if (tz->flags.devices) + acpi_thermal_get_devices(tz); ++ /*User space events will be received from ++ individual devices upon enumeration*/ ++ acpi_thermal_reenumerate(tz); + acpi_bus_generate_event(device, event, 0); + break; + default: +@@ -1168,6 +1861,129 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) + return 0; + } + ++/*Makes a new device (td)under TZ*/ ++static void acpi_thermal_add_td_info(struct kobject *kobj, ++ struct thermal_device_info *info) ++{ ++ int result; ++ ++ if (!kobj || !info) ++ return; ++ ++ kobject_set_name(&info->kobj, info->name); ++ info->kobj.parent = kobj; ++ info->kobj.ktype = &ktype_devices; ++ result = kobject_register(&info->kobj); ++ ++ if (result) ++ return; ++ ++ devices_populate_dir(info); ++} ++ ++/*Adds a thermal device to thermal zone if reported by _TZD*/ ++static int acpi_thermal_verify_td_in_tz(struct acpi_thermal *tz, ++ struct thermal_device *td, ++ enum action_type action) ++{ ++ int i; ++ int result; ++ struct acpi_device *ad; ++ ++ if (!tz || !td) ++ return -EINVAL; ++ ++ /*Loop through _TZD*/ ++ for (i = 0; i < tz->devices.count; i++) { ++ result = acpi_bus_get_device(tz->devices.handles[i], &ad); ++ if (result) ++ return -ENODEV; ++ ++ /*if registered device's name matches _TZD entry add td to tz*/ ++ if (0 == strcmp(td->info.name, ad->pnp.bus_id)) { ++ switch (action) { ++ case THERMAL_ACTION_ADD:{ ++ ACPI_DEBUG_PRINT( ++ (ACPI_DB_INFO, ++ "Registered device %s with \ ++ thermal zone %s\n", ++ td->info.name, ++ tz->name)); ++ ++ tz->info[i] = ++ kzalloc(sizeof ++ (struct ++ thermal_device_info), ++ GFP_KERNEL); ++ ++ memcpy(tz->info[i], &td->info, ++ sizeof(struct ++ thermal_device_info)); ++ ++ acpi_thermal_add_td_info(&tz->kobj, ++ tz->info[i]); ++ return 0; ++ } ++ ++ case THERMAL_ACTION_RMV:{ ++ kobject_unregister(&tz->info[i]->kobj); ++ kfree(tz->info[i]); ++ tz->info[i] = NULL; ++ return 0; ++ } ++ } ++ } ++ ++ } ++ return -ENODEV; ++} ++ ++/* get the list of registered thermal devices ++and add to appropriate thermal zones*/ ++static void acpi_thermal_enumerate(struct acpi_thermal *tz) ++{ ++ struct thermal_device *td = NULL; ++ struct list_head *entry_td; ++ ++ if (!tz) ++ return; ++ ++ /*build info based on _TZD*/ ++ tz->info = kzalloc(tz->devices.count * ++ sizeof(struct thermal_device_info *) ++ , GFP_KERNEL); ++ ++ spin_lock(&td_list_lock); ++ list_for_each(entry_td, ®istered_thermal_device_list) { ++ td = list_entry(entry_td, struct thermal_device, node); ++ acpi_thermal_verify_td_in_tz(tz, td, THERMAL_ACTION_ADD); ++ } ++ spin_unlock(&td_list_lock); ++} ++ ++static void acpi_thermal_reenumerate(struct acpi_thermal *tz) ++{ ++ int i; ++ ++ if (!tz) ++ return; ++ ++ /*Remove first; needed for event ACPI_THERMAL_NOTIFY_DEVICE ++ Loop through _TZD and unregister every kobj*/ ++ for (i = 0; i < tz->devices.count; i++) { ++ if (tz->info[i]) { ++ kobject_unregister(&tz->info[i]->kobj); ++ kfree(tz->info[i]); ++ tz->info[i] = NULL; ++ } ++ } ++ ++ if (tz->info) ++ kfree(tz->info); ++ ++ acpi_thermal_enumerate(tz); ++} ++ + static int acpi_thermal_add(struct acpi_device *device) + { + int result = 0; +@@ -1196,6 +2012,17 @@ static int acpi_thermal_add(struct acpi_device *device) + if (result) + goto end; + ++ /* kobject registering for thermalzone*/ ++ kobject_set_name(&tz->kobj, device->pnp.bus_id); ++ kobj_set_kset_s(tz, thermal_subsys); ++ tz->kobj.parent = &thermal_subsys.kobj; ++ result = kobject_register(&tz->kobj); ++ ++ if (result) ++ goto end; ++ ++ thermalzone_populate_dir(tz); ++ + init_timer(&tz->timer); + + acpi_thermal_check(tz); +@@ -1208,6 +2035,12 @@ static int acpi_thermal_add(struct acpi_device *device) + goto end; + } + ++ acpi_thermal_enumerate(tz); ++ ++ spin_lock(&tz_list_lock); ++ list_add(&(tz->node), &acpi_thermal_list); ++ spin_unlock(&tz_list_lock); ++ + printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", + acpi_device_name(device), acpi_device_bid(device), + KELVIN_TO_CELSIUS(tz->temperature)); +@@ -1215,6 +2048,7 @@ static int acpi_thermal_add(struct acpi_device *device) + end: + if (result) { + acpi_thermal_remove_fs(device); ++ kobject_unregister(&tz->kobj); + kfree(tz); + } + +@@ -1245,6 +2079,9 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) + ACPI_DEVICE_NOTIFY, + acpi_thermal_notify); + ++ list_del(&(tz->node)); ++ kobject_unregister(&tz->kobj); ++ + /* Terminate policy */ + if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { + tz->trips.passive.flags.enabled = 0; +@@ -1256,6 +2093,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) + acpi_thermal_active(tz); + } + ++ kfree(tz->info); + acpi_thermal_remove_fs(device); + + kfree(tz); +@@ -1295,10 +2133,354 @@ static int acpi_thermal_resume(struct acpi_device *device) + return AE_OK; + } + ++/* -------------------------------------------------------------------------- ++ Component Driver Interface ++ -------------------------------------------------------------------------- */ ++ ++/* ++ * thermal_register_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to register ++ * name : ACPI name like CPU0 ++ * class : class as defined in thermal.h ++ * private: context of the device ++ * return : new thermal device ++ */ ++struct thermal_device *thermal_register_device(const char *name, ++ enum participant_class class, ++ void *private) ++{ ++ struct list_head *entry_tz; ++ struct list_head *entry_dd; ++ struct list_head *entry_td; ++ struct thermal_device *td; ++ int result = 0; ++ ++ if (!name) ++ return NULL; ++ ++ /*Check whether the device is already registered*/ ++ spin_lock(&td_list_lock); ++ list_for_each(entry_td, &(registered_thermal_device_list)) { ++ td = list_entry(entry_td, struct thermal_device, node); ++ if (0 == strcmp(name, td->info.name)) { ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Device by the name %s already exists \n", ++ name)); ++ spin_unlock(&td_list_lock); ++ return NULL; ++ } ++ } ++ spin_unlock(&td_list_lock); ++ ++ /*allocate new thermal device*/ ++ td = kzalloc(sizeof(struct thermal_device), GFP_KERNEL); ++ ++ if (!td) ++ return NULL; ++ ++ /*Check whether a driver has registered for this class*/ ++ spin_lock(&dd_list_lock); ++ list_for_each(entry_dd, &thermal_device_driver_list) { ++ struct thermal_device_driver *dd; ++ dd = list_entry(entry_dd, struct thermal_device_driver, node); ++ if (class == dd->class) { ++ td->info.dd = dd; ++ strcpy(td->info.name, name); ++ td->info.private = private; ++ td->info.common = td; ++ break; ++ } ++ } ++ spin_unlock(&dd_list_lock); ++ ++ /*Driver not found*/ ++ if (!td->info.dd) { ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Cannot find a suitable driver for device class %du\n", ++ class)); ++ result = -ENODEV; ++ goto end; ++ } ++ /*Search for enumerated item in each tz*/ ++ spin_lock(&tz_list_lock); ++ list_for_each(entry_tz, &acpi_thermal_list) { ++ struct acpi_thermal *tz; ++ tz = list_entry(entry_tz, struct acpi_thermal, node); ++ acpi_thermal_verify_td_in_tz(tz, td, THERMAL_ACTION_ADD); ++ ++ } ++ spin_unlock(&tz_list_lock); ++ ++ /*Add into the list of registered devices*/ ++ spin_lock(&td_list_lock); ++ list_add(&(td->node), &(registered_thermal_device_list)); ++ spin_unlock(&td_list_lock); ++ ++end: ++ if (result) { ++ kfree(td); ++ td = NULL; ++ } ++ ++ return td; ++} ++EXPORT_SYMBOL(thermal_register_device); ++ ++/*Need to call this function after locking TZ and TD lists*/ ++int __thermal_unregister_device(struct thermal_device *td) ++{ ++ struct list_head *entry_tz; ++ ++ if (!td) ++ return -EINVAL; ++ ++ list_for_each(entry_tz, &acpi_thermal_list) { ++ struct acpi_thermal *tz; ++ tz = list_entry(entry_tz, struct acpi_thermal, node); ++ acpi_thermal_verify_td_in_tz(tz, td, THERMAL_ACTION_RMV); ++ } ++ ++ list_del(&td->node); ++ ++ kfree(td); ++ return 0; ++} ++ ++/* ++ * thermal_unregister_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to unregister ++ * name : ACPI name like CPU0 ++ */ ++int thermal_unregister_device(struct thermal_device *td) ++{ ++ if (!td) ++ return -EINVAL; ++ ++ /*Remove from registered list*/ ++ spin_lock(&tz_list_lock); ++ spin_lock(&td_list_lock); ++ ++ __thermal_unregister_device(td); ++ ++ spin_unlock(&td_list_lock); ++ spin_unlock(&tz_list_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL(thermal_unregister_device); ++ ++/* ++ * thermal_register_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to register ++ * class: as defined in thermal.h ++ * name : ACPI Thermal zone name like TZ00 ++ * ops: callback function as defined in platform sensor driver ++ */ ++int thermal_register_sensor(enum participant_class class, const char *name, ++ struct thermal_sensor_ops *ops) ++{ ++ struct list_head *entry_tz; ++ ++ if (!name || !ops) ++ return -EINVAL; ++ ++ spin_lock(&tz_list_lock); ++ list_for_each(entry_tz, &acpi_thermal_list) { ++ struct acpi_thermal *tz; ++ tz = list_entry(entry_tz, struct acpi_thermal, node); ++ ++ /*Find the matching thermal zone*/ ++ if (0 == strcmp(name, tz->name)) { ++ if (tz->ops) { ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ++ "Already a driver has registered \ ++ for this thermal zone %s \n", ++ tz->name)); ++ spin_unlock(&tz_list_lock); ++ return -EEXIST; ++ } ++ tz->ops = ops; ++ tz->class = class; ++ thermalzone_sensorinfo_populate_dir(tz); ++ ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ++ "Registered sensor for thermal zone %s !\n", ++ tz->name)); ++ ++ spin_unlock(&tz_list_lock); ++ return 0; ++ } ++ } ++ spin_unlock(&tz_list_lock); ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ++ "Failed to register sensor for thermal zone %s \n", ++ name)); ++ return -ENODEV; ++} ++EXPORT_SYMBOL(thermal_register_sensor); ++ ++/* ++ * thermal_unregister_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to unregister ++ * name : ACPI Thermal zone name like TZ00 ++ */ ++int thermal_unregister_sensor(const char *name) ++{ ++ struct list_head *entry_tz; ++ ++ if (!name) ++ return -EINVAL; ++ ++ spin_lock(&tz_list_lock); ++ list_for_each(entry_tz, &acpi_thermal_list) { ++ struct acpi_thermal *tz; ++ tz = list_entry(entry_tz, struct acpi_thermal, node); ++ ++ /*Find the matching thermal zone*/ ++ if (0 == strcmp(name, tz->name) && tz->ops) { ++ tz->ops = NULL; ++ thermalzone_sensorinfo_unpopulate_dir(tz); ++ ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Unregistered sensor for thermal zone %s !\n", ++ tz->name)); ++ spin_unlock(&tz_list_lock); ++ return 0; ++ } ++ } ++ spin_unlock(&tz_list_lock); ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Failed to unregister sensor for thermal zone %s \n", ++ name)); ++ return -ENODEV; ++} ++EXPORT_SYMBOL(thermal_unregister_sensor); ++ ++/* ++ * thermal_register_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance as defined in thermal.h ++ */ ++int thermal_register_device_driver(struct thermal_device_driver *dd) ++{ ++ struct list_head *entry_dd; ++ ++ if (!dd || !dd->ops) ++ return -EINVAL; ++ ++ /*Check whether a driver exists for this class of devices*/ ++ spin_lock(&dd_list_lock); ++ list_for_each(entry_dd, &thermal_device_driver_list) { ++ struct thermal_device_driver *olddd; ++ olddd = ++ list_entry(entry_dd, struct thermal_device_driver, node); ++ if (olddd->class == dd->class) { ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ++ "Already Registered driver \ ++ for class %lu \n", ++ dd->class)); ++ spin_unlock(&dd_list_lock); ++ return -EEXIST; ++ } ++ } ++ ++ /*Add to the list of registered drivers*/ ++ list_add(&(dd->node), &(thermal_device_driver_list)); ++ spin_unlock(&dd_list_lock); ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Registered driver for class %lu \n", ++ dd->class)); ++ return 0; ++} ++EXPORT_SYMBOL(thermal_register_device_driver); ++ ++/* ++ * thermal_unregister_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance as defined in thermal.h ++ */ ++int thermal_unregister_device_driver(struct thermal_device_driver *dd) ++{ ++ struct list_head *pos, *q; ++ struct list_head *entry_dd; ++ int registered = 0; ++ ++ if (!dd) ++ return -EINVAL; ++ ++ /*Check whether a driver is registered*/ ++ spin_lock(&dd_list_lock); ++ list_for_each(entry_dd, &thermal_device_driver_list) { ++ struct thermal_device_driver *olddd; ++ olddd = ++ list_entry(entry_dd, struct thermal_device_driver, node); ++ if (olddd->class == dd->class) { ++ list_del(&dd->node); ++ registered = 1; ++ break; ++ } ++ } ++ spin_unlock(&dd_list_lock); ++ ++ /*Driver is not registered*/ ++ if (!registered) ++ return -EINVAL; ++ ++ /*Remove all the devices associated with this driver ++ TZ lock is needed for __thermal_unregister_device*/ ++ spin_lock(&tz_list_lock); ++ spin_lock(&td_list_lock); ++ list_for_each_safe(pos, q, &(registered_thermal_device_list)) { ++ struct thermal_device *td; ++ td = list_entry(pos, struct thermal_device, node); ++ if (dd == td->info.dd) { ++ /*Shouldn't happen; devices should call unregister_device ++ before unregistering driver*/ ++ __thermal_unregister_device(td); ++ } ++ } ++ spin_unlock(&td_list_lock); ++ spin_unlock(&tz_list_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL(thermal_unregister_device_driver); ++ ++/* ++ * thermal_set_userenabled ++ * ----------------------- ++ * Interface function for platform sensor driver to disble userspace algo ++ * ue: enable / disable userspace algo based on BIOS configuration ++ */ ++int thermal_set_userenabled(enum thermal_userenabled ue) ++{ ++ thermalconfig.userenabled = ue; ++ return 0; ++} ++EXPORT_SYMBOL(thermal_set_userenabled); ++ + static int __init acpi_thermal_init(void) + { + int result = 0; ++ result = subsystem_register(&thermal_subsys); ++ if (result) ++ return result; ++ ++ kobject_set_name(&thermalconfig.kobj, THERMAL_SYSFS_CONFIG); ++ thermalconfig.kobj.parent = &thermal_subsys.kobj; ++ thermalconfig.kobj.ktype = &ktype_thermalconfig; + ++ result = kobject_register(&thermalconfig.kobj); ++ ++ if (result) ++ return result; ++ ++ thermalconfig_populate_dir(&thermalconfig); + + acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); + if (!acpi_thermal_dir) +@@ -1318,7 +2500,7 @@ static void __exit acpi_thermal_exit(void) + { + + acpi_bus_unregister_driver(&acpi_thermal_driver); +- ++ subsystem_unregister(&thermal_subsys); + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); + + return; +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +new file mode 100644 +index 0000000..2332e26 +--- /dev/null ++++ b/include/linux/thermal.h +@@ -0,0 +1,355 @@ ++/* ++ * thermal.h - ACPI Thermal Zone Driver ($Revision: 1 $) ++ * ++ * Copyright (C) 2001, 2002 Andy Grover ++ * Copyright (C) 2001, 2002 Paul Diefenbaugh ++ * Copyright (C) 2001, 2002 Sujith Thomas ++ ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ * ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This driver fully implements the ACPI thermal policy as described in the ++ * ACPI 2.0 Specification. ++ * ++ * TBD: 1. Implement passive cooling hysteresis. ++ * 2. Enhance passive cooling (CPU) states/limit interface to support ++ * concepts of 'multiple limiters', upper/lower limits, etc. ++ * Modified: 1. Provide infrastructure from kernel to enable user-space ++ * thermal management algorithm ++ * ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ACPI_THERMAL_COMPONENT 0x04000000 ++#define ACPI_THERMAL_CLASS "thermal_zone" ++#define ACPI_THERMAL_DRIVER_NAME "ACPI Thermal Zone Driver" ++#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" ++#define ACPI_THERMAL_FILE_STATE "state" ++#define ACPI_THERMAL_FILE_TEMPERATURE "temperature" ++#define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" ++#define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" ++#define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" ++#define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 ++#define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 ++#define ACPI_THERMAL_NOTIFY_DEVICES 0x82 ++#define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 ++#define ACPI_THERMAL_NOTIFY_HOT 0xF1 ++#define ACPI_THERMAL_MODE_ACTIVE 0x00 ++#define ACPI_THERMAL_MODE_PASSIVE 0x01 ++#define ACPI_THERMAL_MODE_CRITICAL 0xff ++#define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" ++ ++#define ACPI_MAX_CHAR 5 ++#define ACPI_THERMAL_MAX_ACTIVE 10 ++#define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 ++ ++#define KELVIN_TO_CELSIUS(t) \ ++ (long)(((long)t-2732 >= 0) ? ((long)t-2732+5)/10 \ ++ : ((long)t-2732-5)/10) ++#define CELSIUS_TO_KELVIN(t) ((t+273)*10) ++ ++struct acpi_thermal_state { ++ u8 critical:1; ++ u8 hot:1; ++ u8 passive:1; ++ u8 active:1; ++ u8 reserved:4; ++ int active_index; ++}; ++ ++struct acpi_thermal_state_flags { ++ u8 valid:1; ++ u8 enabled:1; ++ u8 reserved:6; ++}; ++ ++struct acpi_thermal_critical { ++ struct acpi_thermal_state_flags flags; ++ unsigned long temperature; ++}; ++ ++struct acpi_thermal_hot { ++ struct acpi_thermal_state_flags flags; ++ unsigned long temperature; ++}; ++ ++struct acpi_thermal_passive { ++ struct acpi_thermal_state_flags flags; ++ unsigned long temperature; ++ unsigned long tc1; ++ unsigned long tc2; ++ unsigned long tsp; ++ struct acpi_handle_list devices; ++}; ++ ++struct acpi_thermal_active { ++ struct acpi_thermal_state_flags flags; ++ unsigned long temperature; ++ struct acpi_handle_list devices; ++}; ++ ++struct acpi_thermal_trips { ++ struct acpi_thermal_critical critical; ++ struct acpi_thermal_hot hot; ++ struct acpi_thermal_passive passive; ++ struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; ++}; ++ ++struct acpi_thermal_flags { ++ u8 cooling_mode:1; /* _SCP */ ++ u8 devices:1; /* _TZD */ ++ u8 reserved:6; ++}; ++ ++/*By default kernel increments CPU throttlinby one step at a time*/ ++#define THROTTLE_INCREMENT_STEP 1 ++#define THROTTLE_DECREMENT_STEP -1 ++ ++/*Support for absolute or relative throttlestates ++ Relative is the one used by default kernel algorithm*/ ++#define THERMAL_MAX_THROTTLE_TYPE 2 ++enum throttle_set_type { THROTTLE_ABS, THROTTLE_REL }; ++ ++/*Permissible Step range for relative throttling*/ ++#define MAX_THROTTLE_STEP 9 ++#define MIN_THROTTLE_STEP -9 ++ ++/* -------------------------------------------------------------------------- ++ Component Driver Interface ++ -------------------------------------------------------------------------- */ ++/*Reserved */ ++#define DEVICE_CAPS_RESERVED 0x000000 ++/*Has H/W thermal trip/throttle */ ++#define DEVICE_CAPS_HW_THROTTLE 0x000001 ++/*Has S/W programmable thermal events */ ++#define DEVICE_CAPS_SW_PGM_THERMAL_EVENTS 0x000002 ++/*Has thermal throttle controls (Non/Linear) */ ++#define DEVICE_CAPS_THROTTLE_CONTROLS 0x000004 ++/*Active device (e.g. Fan, Pump)" */ ++#define DEVICE_CAPS_ACTIVE 0x000008 ++/*Has monotonic throttle states */ ++#define DEVICE_CAPS_MONOTONIC_STATES 0x000010 ++ ++typedef int (*thermal_device_set_throttle_limit) (enum throttle_set_type type, ++ void *data, const char *buf); ++typedef int (*thermal_device_get_throttle_limit) (void *data, char *buf); ++typedef int (*thermal_device_get_max_throttle_limit) (void *data, char *buf); ++typedef int (*thermal_device_get_caps) (void *data, char *buf); ++ ++struct thermal_device_ops { ++ /*Set new throttle limit */ ++ thermal_device_set_throttle_limit setthrottlelimit; ++ /*Get current throttle limit */ ++ thermal_device_get_throttle_limit getthrottlelimit; ++ /*Get maximum suppoted throttle state */ ++ thermal_device_get_max_throttle_limit getmaxthrottlelimit; ++ /*Get device capabilities */ ++ thermal_device_get_caps getcaps; ++}; ++ ++struct thermal_device_driver { ++ struct list_head node; /*Linked list handling */ ++ unsigned long class; /*Device class */ ++ struct thermal_device_ops *ops; /*Callback functions */ ++}; ++ ++struct thermal_device_info { ++ char name[ACPI_MAX_CHAR]; /*ACPI name */ ++ void *private; /*Device specific data */ ++ struct thermal_device_driver *dd; /*Device driver info */ ++ /*Info common to same devices in different TZs */ ++ struct thermal_device *common; ++ struct kobject kobj; /*Sysfs stuff */ ++}; ++ ++struct thermal_device { ++ struct list_head node; /*Linked list handling */ ++ enum throttle_set_type type; /*Absoulute/Relative */ ++ struct thermal_device_info info;/*name + driver details + kobj */ ++}; ++ ++enum participant_class { THERMAL_UNKNOWN_CLASS, THERMAL_SKIN_CLASS, ++ THERMAL_SYSTEM_CLASS, THERMAL_CPU_CLASS, THERMAL_MEM_CLASS, ++ THERMAL_LCD_CLASS, THERMAL_GFX_CLASS, THERMAL_WLAN_CLASS, ++ THERMAL_WWAN_CLASS, THERMAL_ACTIVE_CLASS ++}; ++ ++enum action_type { THERMAL_ACTION_ADD, THERMAL_ACTION_RMV }; ++ ++/*Interface functions for component registration*/ ++ ++/* ++ * thermal_register_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to register ++ * name : ACPI name like CPU0 ++ * class : class as defined in thermal.h ++ * private: context of the device ++ * return : a pointer to new thermal device ++ */ ++struct thermal_device *thermal_register_device(const char *name, ++ enum participant_class class, ++ void *private); ++/* ++ * thermal_unregister_device ++ * ---------------------- ++ * Interface function for devices like CPU,LCD ... to unregister ++ * name : ACPI thermal device * ++ */ ++int thermal_unregister_device(struct thermal_device *td); ++ ++/* ++ * thermal_register_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance as defined in thermal.h ++ */ ++int thermal_register_device_driver(struct thermal_device_driver *dd); ++ ++/* ++ * thermal_unregister_device_driver ++ * ----------------------------- ++ * Interface function for platform sensor driver to unregister ++ * dd : thermal_device_driver instance as defined in thermal.h ++ */ ++int thermal_unregister_device_driver(struct thermal_device_driver *dd); ++ ++/* -------------------------------------------------------------------------- ++ Sensor Driver Interface ++ -------------------------------------------------------------------------- */ ++ ++/*Sensor capabilities*/ ++ ++/* Reserved */ ++#define SENSOR_CAPS_RESERVED 0x000000 ++/*Can support multiple participant devices */ ++#define SENSOR_CAPS_MULTIPLE_DEVICES 0x000001 ++/*Can report temperature */ ++#define SENSOR_CAPS_REPORT_TEMP 0x000002 ++/*Reports relative or absolute temperature */ ++#define SENSOR_CAPS_REPORT_ABS_TEMP 0x000004 ++/*Reports average or instantaneous temp */ ++#define SENSOR_CAPS_REPORT_INST_TEMP 0x000008 ++/* Programmable sample interval */ ++#define SENSOR_CAPS_PGM_SAMPLE_INT 0x000010 ++/*Can report rate-of-change */ ++#define SENSOR_CAPS_REPORT_RATE 0x000040 ++/* Has H/W thermal trip/throttle */ ++#define SENSOR_CAPS_HW_THERMAL_TRIP 0x010000 ++/*Has S/W programmable thermal events */ ++#define SENSOR_CAPS_SW_PGM_THERMAL_EVENTS 0x020000 ++/*Has ACPI thermal trip points */ ++#define SENSOR_CAPS_ACPI_THERMAL_TRIPS 0x040000 ++ ++/*Sensor temperature base*/ ++#define SENSOR_TEMPBASE_ABS_KELVIN 0x00 ++#define SENSOR_TEMPBASE_REL_KELVIN 0x01 ++#define SENSOR_TEMPBASE_ABS_CELSIUS 0x02 ++#define SENSOR_TEMPBASE_REL_CELSIUS 0x03 ++ ++enum aux_type { THERMAL_AUX0, THERMAL_AUX1 }; ++ ++typedef int (*thermal_sensor_set_aux_trip) (const char *name, const int auxtype, ++ const char *buf); ++typedef int (*thermal_sensor_get_aux_trip) (const char *name, const int auxtype, ++ char *buf); ++typedef int (*thermal_sensor_get_temp_base) (const char *name, char *buf); ++typedef int (*thermal_sensor_get_caps) (const char *name, char *buf); ++ ++struct thermal_sensor_ops { ++ thermal_sensor_set_aux_trip setauxtrip; /*Get current AUX trip */ ++ thermal_sensor_get_aux_trip getauxtrip; /*Set new AUX trip */ ++ thermal_sensor_get_temp_base gettempbase;/*Get temperature base (K/c) */ ++ thermal_sensor_get_caps getcaps; /*Get sensor capabilities */ ++}; ++/*Interface functions for platform sensor driver registration*/ ++ ++/* ++ * thermal_register_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to register ++ * class: as defined in thermal.h ++ * name : ACPI Thermal zone name like TZ00 ++ * ops: callback function as defined in platform sensor driver ++ */ ++int thermal_register_sensor(enum participant_class class, const char *name, ++ struct thermal_sensor_ops *ops); ++ ++/* ++ * thermal_unregister_sensor ++ * ---------------------- ++ * Interface function for platform sensor driver to unregister ++ * name : ACPI Thermal zone name like TZ00 ++ */ ++int thermal_unregister_sensor(const char *name); ++ ++/* -------------------------------------------------------------------------- ++ Configuration Interface ++ -------------------------------------------------------------------------- */ ++ ++#define THERMAL_SYSFS_CONFIG "config" ++ ++#define THERMAL_MAX_MODE 2 ++enum thermal_userenabled { THERMAL_USER_DISABLED, THERMAL_USER_ENABLED }; ++enum thermal_mode { THERMAL_USERSPACE, THERMAL_KERNELSPACE }; ++ ++struct thermal_config { ++ u8 userenabled:1; /* 1 if user application is allowed to take over */ ++ u8 mode:1; /* 0 if userspace algorithm has taken over */ ++ struct kobject kobj;/*Syfs stuff */ ++}; ++ ++/* ++ * thermal_set_userenabled ++ * ----------------------- ++ * Interface function for platform sensor driver to disble userspace algo ++ * ue: enable / disable userspace algo based on BIOS configuration ++ */ ++int thermal_set_userenabled(enum thermal_userenabled um); ++ ++/* -------------------------------------------------------------------------- ++ Thermal zone definition ++ -------------------------------------------------------------------------- */ ++struct acpi_thermal { ++ struct list_head node; /*Linkedlist management */ ++ struct acpi_device *device; /*ACPI device info */ ++ acpi_bus_id name; /*ACPI device name (eg:- TZ00) */ ++ unsigned long temperature; /*Current temperature */ ++ unsigned long last_temperature; /*Previous temperature */ ++ unsigned long polling_frequency;/*Polling fequency */ ++ u8 cooling_mode; /*Active or passive */ ++ volatile u8 zombie; /*Flag for avoiding new deferred task */ ++ struct acpi_thermal_flags flags;/*See definition above */ ++ struct acpi_thermal_state state;/*See definition above */ ++ struct acpi_thermal_trips trips;/*_CRT,_HOT,_PSV*/ ++ struct acpi_handle_list devices;/* _TZD */ ++ struct timer_list timer; /*Timer for polling thermal zone */ ++ struct thermal_device_info **info;/*Array of devices in TZ */ ++ /*Call back functions to platform sensor driver */ ++ struct thermal_sensor_ops *ops; ++ enum participant_class class;/*Participant (device + sensor) class */ ++ struct kobject kobj; /*Syfs stuff */ ++}; +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0005-Thermal-Poulsbo-AUX-trip-point-support.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0005-Thermal-Poulsbo-AUX-trip-point-support.patch @@ -0,0 +1,406 @@ +From 08d09f95e88e7aa1f08c86317fbba9c7e2bf26ed Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: AUX trip point support + +- Support for programming AUX trip points of Intel platform Poulsbo +- Support for disabling user space thermal management from BIOS +- Register/Unregister with thermal driver and expose AUX programming interface + +Signed-off-by: Sujith Thomas +--- + drivers/acpi/Kconfig | 8 + + drivers/acpi/Makefile | 1 + + drivers/acpi/thermal_sensor.c | 349 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 358 insertions(+), 0 deletions(-) + create mode 100644 drivers/acpi/thermal_sensor.c + +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index ad9f836..c8f50c0 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -182,6 +182,14 @@ config ACPI_HOTPLUG_CPU + select ACPI_CONTAINER + default y + ++config THERMAL_SENSOR ++ tristate "Thermal sensor driver" ++ depends on ACPI_THERMAL ++ default y ++ help ++ This driver adds support for AUX trip programming of sensors withing ACPI thermal zones. This is an intel platform specific driver. ++ ++ + config ACPI_NUMA + bool "NUMA support" + depends on NUMA +diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile +index d4336f1..4cda36c 100644 +--- a/drivers/acpi/Makefile ++++ b/drivers/acpi/Makefile +@@ -52,6 +52,7 @@ obj-$(CONFIG_ACPI_POWER) += power.o + obj-$(CONFIG_ACPI_PROCESSOR) += processor.o + obj-$(CONFIG_ACPI_CONTAINER) += container.o + obj-$(CONFIG_ACPI_THERMAL) += thermal.o ++obj-$(CONFIG_THERMAL_SENSOR) += thermal_sensor.o + obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o + obj-$(CONFIG_ACPI_DEBUG) += debug.o + obj-$(CONFIG_ACPI_NUMA) += numa.o +diff --git a/drivers/acpi/thermal_sensor.c b/drivers/acpi/thermal_sensor.c +new file mode 100644 +index 0000000..d203a86 +--- /dev/null ++++ b/drivers/acpi/thermal_sensor.c +@@ -0,0 +1,349 @@ ++/* ++ * thermal_sensor.c - Platform specific sensor Driver ($Revision: 1 $) ++ * Copyright (C) 2001, 2002 Sujith Thomas ++ ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ * ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This driver fully implements the platform sensor driver aux progamming ++ * for intel formfactor device 'Donley' ++ * ++ * It makes use of the acpi_ec driver to communicate to all the sensors ++ * in the platform which are connected to EC ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Sujith Thomas"); ++MODULE_DESCRIPTION("Thermal sensor driver"); ++MODULE_LICENSE("GPL"); ++ ++/*Offsets in EC memory region for Poulsbo*/ ++#define OFFSET_SKN0_AUX0 131/*Top skin*/ ++#define OFFSET_SKN0_AUX1 132 ++#define OFFSET_SKN1_AUX0 128/*Bottom skin*/ ++#define OFFSET_SKN1_AUX1 129 ++#define OFFSET_CPU_AUX0 125/*CPU*/ ++#define OFFSET_CPU_AUX1 126 ++#define OFFSET_MEM_AUX0 134/*Memory*/ ++#define OFFSET_MEM_AUX1 135 ++ ++ ++ ++#define MAX_AUX_COUNT 2 ++#define MAX_SENSOR_COUNT 5 ++#define TZ_PREFIX "TZ" ++ ++/*Macros for reading an ACPI object from ACPI namespace*/ ++static acpi_handle root_handle; ++ ++ ++#define THERMAL_ACPI_HANDLE(object, parent, paths...) \ ++ static acpi_handle object##_handle; \ ++ static acpi_handle *object##_parent = &parent##_handle; \ ++ static char *object##_path; \ ++ static char *object##_paths[] = { paths } \ ++ ++ ++THERMAL_ACPI_HANDLE(user_algo, root, "\\_TZ"); ++ ++#define THERMAL_ACPI_HANDLE_INIT(object) \ ++ thermal_acpi_handle_init( \ ++ #object, &object##_handle \ ++ , *object##_parent, object##_paths\ ++ , ARRAY_SIZE(object##_paths) \ ++ , &object##_path \ ++ ) ++ ++struct thermal_sensor_info { ++ /*Currently only AUX0 & AUX1 are supported*/ ++ int aux[MAX_AUX_COUNT]; ++ enum participant_class class; /*as defined in thermal.h*/ ++ char name[ACPI_MAX_CHAR]; /*ACPI name*/ ++ unsigned long caps; /*Device capabilities*/ ++ unsigned long tempbase; /*Temperature base (Kelvin/Celsius)*/ ++}; ++ ++static struct thermal_sensor_info thermal_sensor_infos[MAX_SENSOR_COUNT] = { ++ { ++ .aux[THERMAL_AUX0] = OFFSET_CPU_AUX0, ++ .aux[THERMAL_AUX1] = OFFSET_CPU_AUX1, ++ .class = THERMAL_CPU_CLASS, ++ .name = "TZ00", ++ .caps = SENSOR_CAPS_REPORT_TEMP, ++ .tempbase = SENSOR_TEMPBASE_ABS_CELSIUS, ++ }, ++ { ++ .aux[THERMAL_AUX0] = OFFSET_CPU_AUX0, ++ .aux[THERMAL_AUX1] = OFFSET_CPU_AUX1, ++ .class = THERMAL_CPU_CLASS, ++ .name = "TZ01", ++ .caps = SENSOR_CAPS_REPORT_TEMP, ++ .tempbase = SENSOR_TEMPBASE_ABS_CELSIUS, ++ }, ++ { ++ .aux[THERMAL_AUX0] = OFFSET_MEM_AUX0, ++ .aux[THERMAL_AUX1] = OFFSET_MEM_AUX1, ++ .class = THERMAL_MEM_CLASS, ++ .name = "TZ02", ++ .caps = SENSOR_CAPS_REPORT_TEMP, ++ .tempbase = SENSOR_TEMPBASE_ABS_CELSIUS, ++ }, ++ { ++ .aux[THERMAL_AUX0] = OFFSET_SKN1_AUX0, ++ .aux[THERMAL_AUX1] = OFFSET_SKN1_AUX1, ++ .class = THERMAL_SKIN_CLASS, ++ .name = "TZ03", ++ .caps = SENSOR_CAPS_REPORT_TEMP, ++ .tempbase = SENSOR_TEMPBASE_ABS_CELSIUS, ++ }, ++ { ++ .aux[THERMAL_AUX0] = OFFSET_SKN0_AUX0, ++ .aux[THERMAL_AUX1] = OFFSET_SKN0_AUX1, ++ .class = THERMAL_SKIN_CLASS, ++ .name = "TZ04", ++ .caps = SENSOR_CAPS_REPORT_TEMP, ++ .tempbase = SENSOR_TEMPBASE_ABS_CELSIUS, ++ }, ++}; ++ ++/* ++ * sensor_get_id ++ * ------------- ++ * Convert the name to an ID in the thermal_sensor_infos ++ * name: Thermalzone name ++ */ ++static int sensor_get_id(const char *name) ++{ ++ int id; ++ char *tzID = strstr(name, TZ_PREFIX); ++ ++ if (!name) ++ return -EINVAL; ++ ++ id = strtoul(tzID + strlen(TZ_PREFIX), NULL, 0); ++ ++ if (id >= MAX_SENSOR_COUNT) { ++ return -ENODEV; ++ } ++ ++ return id; ++} ++ ++/* ++ * sensor_get_auxtrip ++ * ----------------- ++ * get the current auxtrip value from sensor throughec ++ * name: Thermalzone name ++ * auxtype : AUX0/AUX1 ++ * buf: syfs buffer ++ */ ++static int sensor_get_auxtrip(const char *name, const int auxtype, char *buf) ++{ ++ int ret = 0; ++ int id; ++ u8 data; ++ ++ if (!name || !buf) ++ return -EINVAL; ++ ++ id = sensor_get_id(name); ++ if (id < 0) ++ return -ENODEV; ++ ++ ret = ec_read(thermal_sensor_infos[id].aux[auxtype], &data); ++ if (ret) ++ return -EIO; ++ ++ sprintf(buf, "%d \n", data); ++ ++ return ret; ++} ++ ++/* ++ * sensor_set_auxtrip ++ * ----------------- ++ * set the new auxtrip value to sensor through ec ++ * name: Thermalzone name ++ * auxtype : AUX0/AUX1 ++ * buf: syfs buffer ++ */ ++static int sensor_set_auxtrip(const char *name, const int auxtype, ++ const char *buf) ++{ ++ int ret = 0; ++ int id; ++ u8 data; ++ u8 cmp_data; ++ ++ if (!name || !buf) ++ return -EINVAL; ++ ++ id = sensor_get_id(name); ++ if (id < 0) ++ return ret; ++ ++ data = strtoul(buf, NULL, 0); ++ ++ /*Sanity check aux0 < aux1*/ ++ if (THERMAL_AUX0 == auxtype) { ++ ret = ++ ec_read(thermal_sensor_infos[id].aux[THERMAL_AUX1], ++ &cmp_data); ++ if (ret) ++ return -EIO; ++ if (data > cmp_data) ++ return -EINVAL; ++ } else if (THERMAL_AUX1 == auxtype) { ++ ret = ++ ec_read(thermal_sensor_infos[id].aux[THERMAL_AUX0], ++ &cmp_data); ++ if (ret) ++ return -EIO; ++ if (data < cmp_data) ++ return -EINVAL; ++ } ++ ++ ret = ec_write(thermal_sensor_infos[id].aux[auxtype], data); ++ ++ if (ret) ++ return -EIO; ++ ++ return ret; ++} ++ ++/* ++ * sensor_get_caps ++ * ----------------- ++ * get the capabilities of sensor ++ * name: Thermalzone name ++ * buf: syfs buffer ++ */ ++static int sensor_get_caps(const char *name, char *buf) ++{ ++ int ret = 0; ++ int id; ++ ++ if (!name || !buf) ++ return -EINVAL; ++ ++ id = sensor_get_id(name); ++ if (id < 0) ++ return ret; ++ ++ sprintf(buf, "%lu \n", thermal_sensor_infos[id].caps); ++ ++ return 0; ++} ++ ++/* ++ * sensor_get_tempbase ++ * ----------------- ++ * get the temperature base (Kelvin /Celsius) ++ * name: Thermalzone name ++ * buf: syfs buffer ++ */ ++static int sensor_get_tempbase(const char *name, char *buf) ++{ ++ int ret = 0; ++ int id; ++ ++ if (!name || !buf) ++ return -EINVAL; ++ ++ id = sensor_get_id(name); ++ if (id < 0) ++ return ret; ++ ++ sprintf(buf, "%lu \n", thermal_sensor_infos[id].tempbase); ++ ++ return 0; ++} ++ ++static void __init thermal_acpi_handle_init(char *name, ++ acpi_handle * handle, ++ acpi_handle parent, char **paths, ++ int num_paths, char **path) ++{ ++ int i; ++ acpi_status status; ++ ++ for (i = 0; i < num_paths; i++) { ++ status = acpi_get_handle(parent, paths[i], handle); ++ if (ACPI_SUCCESS(status)) { ++ *path = paths[i]; ++ return; ++ } ++ } ++ ++ *handle = NULL; ++} ++ ++static struct thermal_sensor_ops ops = { ++ .setauxtrip = sensor_set_auxtrip, ++ .getauxtrip = sensor_get_auxtrip, ++ .gettempbase = sensor_get_tempbase, ++ .getcaps = sensor_get_caps, ++}; ++ ++static int __init thermalsensor_start(void) ++{ ++ int i; ++ struct acpi_buffer result, *resultp; ++ union acpi_object out_obj; ++ acpi_status status = AE_OK; ++ ++ /*Register all the supported sensors*/ ++ for (i = 0; i < MAX_SENSOR_COUNT; i++) { ++ if (0 != ++ thermal_register_sensor(thermal_sensor_infos[i].class, ++ thermal_sensor_infos[i].name, &ops)) ++ printk(KERN_INFO "Failed to register \ ++ sensor for thermalzone %s\n", ++ thermal_sensor_infos[i].name); ++ } ++ ++ THERMAL_ACPI_HANDLE_INIT(user_algo); ++ ++ result.length = sizeof(out_obj); ++ result.pointer = &out_obj; ++ resultp = &result; ++ ++ /*Check whether the user application is enabled in BIOS*/ ++ status = acpi_evaluate_object(user_algo_handle, "DSTS", NULL, resultp); ++ if (ACPI_FAILURE(status) ++ || THERMAL_USER_DISABLED == out_obj.integer.value) ++ thermal_set_userenabled(THERMAL_USER_DISABLED); ++ ++ return 0; ++} ++ ++static void __exit thermalsensor_end(void) ++{ ++ int i; ++ /*Unregister all the sensors*/ ++ for (i = 0; i < MAX_SENSOR_COUNT; i++) { ++ thermal_unregister_sensor(thermal_sensor_infos[i].name); ++ } ++} ++ ++module_init(thermalsensor_start); ++module_exit(thermalsensor_end); +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0003-Thermal-Poulsbo-register-to-thermal-driver.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0003-Thermal-Poulsbo-register-to-thermal-driver.patch @@ -0,0 +1,431 @@ +From fa3683edfad62dee199990e10b4f3a1eac52f462 Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: register to thermal driver + +-Register/Unregister with ACPI thermal driver +-Exports the callbacks for switching P and T states +-Support for absolute and relative switching of P and T states + +Signed-off-by: Sujith Thomas +--- + drivers/acpi/Kconfig | 2 +- + drivers/acpi/processor_core.c | 334 +++++++++++++++++++++++++++++++++++++++++ + include/acpi/processor.h | 1 + + 3 files changed, 336 insertions(+), 1 deletions(-) + +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index 3c74305..07ae366 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -168,6 +168,7 @@ config ACPI_VIDEO + + config ACPI_PROCESSOR + tristate "Processor" ++ depends on ACPI_THERMAL + default y + help + This driver installs ACPI as the idle handler for Linux, and uses +@@ -181,7 +182,6 @@ config ACPI_HOTPLUG_CPU + select ACPI_CONTAINER + default y + +- + config ACPI_NUMA + bool "NUMA support" + depends on NUMA +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index f7de02a..b493641 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -58,6 +58,7 @@ + #include + #include + ++#include + #define ACPI_PROCESSOR_COMPONENT 0x01000000 + #define ACPI_PROCESSOR_CLASS "processor" + #define ACPI_PROCESSOR_DEVICE_NAME "Processor" +@@ -724,6 +725,12 @@ static int acpi_processor_add(struct acpi_device *device) + strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); + acpi_driver_data(device) = pr; ++ /* registering with tz driver */ ++ pr->td = ++ thermal_register_device(device->pnp.bus_id, THERMAL_CPU_CLASS, pr); ++ if (!pr->td) ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ++ " Failed to register with thermal zonefrom ACPI CPU driver ")); + + return 0; + } +@@ -748,6 +755,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) + if (acpi_processor_handle_eject(pr)) + return -EINVAL; + } ++ /*Unregister with the thermal zone driver*/ ++ thermal_unregister_device(pr->td); + + acpi_processor_power_exit(pr, device); + +@@ -991,6 +1000,327 @@ void acpi_processor_uninstall_hotplug_notify(void) + * ACPI, but needs symbols from this driver + */ + ++/* -------------------------------------------------------------------------- ++ Thermal management APIs ++ -------------------------------------------------------------------------- */ ++struct acpi_processor_states { ++ u16 pstate; ++ u16 tstate; ++}; ++ ++#define MAXFREQ_STATE 0 ++#define THROTTLE_STATE 1 ++ ++#define PSTATE_NOT_SUPPORTED 0 ++#define TSTATE_NOT_SUPPORTED 0 ++ ++/* ++ * cpu_get_max_state ++ * ----------------------------- ++ * Fills back the maximum permissible P-states and T-States ++ * pr : acpi_processor (processor context) ++ * states : OUT param with Max P & T states ++ */ ++ ++static int cpu_get_max_state(struct acpi_processor *pr, ++ struct acpi_processor_states *states) ++{ ++ if (!pr || !states) ++ return -EINVAL; ++ ++ if ((!pr->performance) && (!(pr->throttling.state_count > 0))) { ++ states->tstate = TSTATE_NOT_SUPPORTED; ++ states->pstate = PSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!pr->performance) { ++ states->tstate = pr->throttling.state_count; ++ states->pstate = PSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!(pr->throttling.state_count > 0)) { ++ states->tstate = TSTATE_NOT_SUPPORTED; ++ states->pstate = pr->performance->state_count; ++ } ++ ++ else { ++ states->tstate = pr->throttling.state_count; ++ states->pstate = pr->performance->state_count; ++ } ++ ++ return 0; ++} ++ ++/* ++ * cpu_get_current_state ++ * ----------------------------- ++ * Fills back the current P-states and T-States ++ * pr : acpi_processor (processor context) ++ * states : OUT param with current P & T states ++ */ ++static int cpu_get_current_state(struct acpi_processor *pr, ++ struct acpi_processor_states *states) ++{ ++ if (!pr || !states) ++ return -EINVAL; ++ ++ if ((!pr->performance) && (!(pr->throttling.state_count > 0))) { ++ states->pstate = PSTATE_NOT_SUPPORTED; ++ states->tstate = TSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!pr->performance) { ++ states->tstate = pr->throttling.state; ++ states->pstate = PSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!(pr->throttling.state_count > 0)) { ++ states->tstate = TSTATE_NOT_SUPPORTED; ++ states->pstate = pr->performance->state; ++ } ++ ++ else { ++ states->tstate = pr->throttling.state; ++ states->pstate = pr->performance->state; ++ } ++ ++ return 0; ++} ++ ++/* ++ * cpu_get_next_state ++ * ----------------------------- ++ * Fills back the next possible combination of P-states and T-States ++ * Always P-states are exhausted and then the T-states ++ * pr : acpi_processor (processor context) ++ * states : OUT param with next possible P & T states ++ */ ++ ++/*We need to get the next state as below*/ ++/* ++0 1 2 3 4 5 6 7 8 9 10 ++========================================= ++P0 P1 P2 ++ T0 T1 T2 T3 T4 T5 T6 T7 ++*/ ++static int cpu_get_next_state(int step, struct acpi_processor *pr, ++ struct acpi_processor_states *states) ++{ ++ int result; ++ int new_pstate; ++ struct acpi_processor_states cur_states, max_states; ++ ++ if (!pr || !states) ++ return -EINVAL; ++ ++ cpu_get_max_state(pr, &max_states); ++ cpu_get_current_state(pr, &cur_states); ++ ++ /*Initialize to current*/ ++ memcpy(states, &cur_states, sizeof(struct acpi_processor_states)); ++ ++ /*If the value goes beyond lower limit set states to high performance*/ ++ if (cur_states.pstate + cur_states.tstate + step <= 0) { ++ states->pstate = 0; ++ states->tstate = 0; ++ result = MAXFREQ_STATE; ++ } ++ /*If the value goes beyond upper limit set states to low performance*/ ++ else if (cur_states.tstate + step > max_states.tstate) { ++ states->pstate = max_states.pstate; ++ states->tstate = max_states.tstate; ++ result = THROTTLE_STATE; ++ } ++ /*If the 'step' partiailly inclues P-state ++ and partially includes T-state*/ ++ else if (cur_states.pstate + (cur_states.tstate + 1) + step >= ++ max_states.pstate) { ++ new_pstate = ++ max_states.pstate - 1 >= 0 ? max_states.pstate - 1 : 0; ++ states->pstate = new_pstate; ++ states->tstate += cur_states.pstate + step - new_pstate; ++ result = THROTTLE_STATE; ++ } ++ /*If step is in a valid P-state range*/ ++ else { ++ states->pstate += step; ++ result = THROTTLE_STATE; ++ } ++ ++ return result; ++} ++ ++/* -------------------------------------------------------------------------- ++ Thermal management sysfs callbacks ++ -------------------------------------------------------------------------- */ ++ ++/* ++ * cpu_device_set_throttle_limit ++ * ----------------------------- ++ * call back function for setting the device's new throttle limit ++ * data : acpi_processor ++ * buf : sysfs buffer that contains the data ++ */ ++int cpu_device_set_throttle_limit(enum throttle_set_type type, ++ void *data, const char *buf) ++{ ++ struct acpi_processor *pr = (struct acpi_processor *)data; ++ struct acpi_processor_performance *perf; ++ struct cpufreq_policy policy; ++ struct acpi_processor_states states; ++ ++ int new_state; ++ int step; ++ unsigned int pstate; ++ unsigned int tstate; ++ ++ int result = 0; ++ ++ perf = pr->performance; ++ ++ if (!buf) ++ return -EFAULT; ++ ++ /*Absolute throttle*/ ++ if (THROTTLE_ABS == type) { ++ new_state = simple_strtol(buf, NULL, 0); ++ if (new_state < 0) ++ return -EINVAL; ++ ++ memcpy(&states, &new_state, sizeof(unsigned int)); ++ ++ } ++ /*Relative thorttle*/ ++ else { ++ step = simple_strtol(buf, NULL, 0); ++ cpu_get_next_state(step, pr, &states); ++ } ++ ++ pstate = states.pstate; ++ tstate = states.tstate; ++ ++ if (perf && pstate < perf->state_count && pstate != perf->state) { ++ cpufreq_get_policy(&policy, pr->id); ++ policy.max = perf->states[pstate].core_frequency * 1000; ++ result = cpufreq_set_policy(&policy); ++ ++ if (result) ++ return result; ++ ++ pr->performance->state = pstate; ++ } ++ ++ result = 0; ++ ++ if (tstate < pr->throttling.state_count ++ && tstate != pr->throttling.state) ++ result = acpi_processor_set_throttling(pr, tstate); ++ ++ return result; ++} ++ ++/* ++ * cpu_device_get_throttle_limit ++ * ----------------------------- ++ * call back function for getting the device's current throttle limit ++ * data : acpi_processor ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int cpu_device_get_throttle_limit(void *data, char *buf) ++{ ++ struct acpi_processor *pr = (struct acpi_processor *)data; ++ int throttlestate; ++ struct acpi_processor_states states; ++ ++ char *s = buf; ++ ++ if (!pr) ++ return -EINVAL; ++ ++ cpu_get_current_state(pr, &states); ++ ++ memcpy(&throttlestate, &states, sizeof(unsigned int)); ++ s += sprintf(s, "%d\n", throttlestate); ++ ++ return 0; ++} ++ ++/* ++ * cpu_device_get_maxthrottle_limit ++ * ----------------------------- ++ * call back function for getting the device's maximum throttle limit ++ * data : acpi_processor ++ * buf : sysfs buffer that needs to be filled back ++ */ ++int cpu_device_get_maxthrottle_limit(void *data, char *buf) ++{ ++ int maxthrottlestate = 0; ++ char *s = buf; ++ struct acpi_processor_states states; ++ struct acpi_processor *pr = (struct acpi_processor *)data; ++ ++ if (!pr) ++ return -EINVAL; ++ ++ if ((!pr->performance) && (!(pr->throttling.state_count > 0))) { ++ states.tstate = TSTATE_NOT_SUPPORTED; ++ states.pstate = PSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!pr->performance) { ++ states.tstate = pr->throttling.state_count; ++ states.pstate = PSTATE_NOT_SUPPORTED; ++ } ++ ++ else if (!(pr->throttling.state_count > 0)) { ++ states.tstate = TSTATE_NOT_SUPPORTED; ++ states.pstate = pr->performance->state_count; ++ } ++ ++ else { ++ states.tstate = pr->throttling.state_count; ++ states.pstate = pr->performance->state_count; ++ } ++ ++ memcpy(&maxthrottlestate, &states, sizeof(unsigned int)); ++ s += sprintf(s, "%d\n", maxthrottlestate); ++ ++ return 0; ++} ++ ++/* ++ * cpu_device_get_caps ++ * ----------------------------- ++ * call back function for getting the device's capabilities ++ * data : acpi_processor ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int cpu_device_get_caps(void *data, char *buf) ++{ ++ char *s = buf; ++ unsigned int caps = 0; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ caps |= DEVICE_CAPS_SW_PGM_THERMAL_EVENTS; ++ s += sprintf(buf, "%d\n", caps); ++ ++ return (s - buf); ++} ++ ++static struct thermal_device_ops cpu_thermal_ops = { ++ .getthrottlelimit = cpu_device_get_throttle_limit, ++ .setthrottlelimit = cpu_device_set_throttle_limit, ++ .getmaxthrottlelimit = cpu_device_get_maxthrottle_limit, ++ .getcaps = cpu_device_get_caps, ++}; ++ ++static struct thermal_device_driver cpu_thermal_driver = { ++ .class = THERMAL_CPU_CLASS, ++ .ops = &cpu_thermal_ops ++}; ++ + static int __init acpi_processor_init(void) + { + int result = 0; +@@ -1010,6 +1340,8 @@ static int __init acpi_processor_init(void) + return -ENOMEM; + acpi_processor_dir->owner = THIS_MODULE; + ++ thermal_register_device_driver(&cpu_thermal_driver); ++ + result = acpi_bus_register_driver(&acpi_processor_driver); + if (result < 0) { + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); +@@ -1036,6 +1368,8 @@ static void __exit acpi_processor_exit(void) + + acpi_bus_unregister_driver(&acpi_processor_driver); + ++ thermal_unregister_device_driver(&cpu_thermal_driver); ++ + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); + + return; +diff --git a/include/acpi/processor.h b/include/acpi/processor.h +index b4b0ffd..2e5d221 100644 +--- a/include/acpi/processor.h ++++ b/include/acpi/processor.h +@@ -177,6 +177,7 @@ struct acpi_processor { + + /* the _PDC objects for this processor, if any */ + struct acpi_object_list *pdc; ++ struct thermal_device *td; + }; + + struct acpi_processor_errata { +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0006-Thermal-Poulsbo-Thottling-support-from-SMI.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0006-Thermal-Poulsbo-Thottling-support-from-SMI.patch @@ -0,0 +1,440 @@ +From c60b635637f0baadc4cc937519f11634f5a0d0f8 Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: Thottling support from SMI + +- Generic support for throttling of any component using SMI +- Memory throttling for Intel platform Poulsbo + +Signed-off-by: Sujith Thomas +--- + drivers/acpi/Kconfig | 13 +++ + drivers/acpi/Makefile | 2 + + drivers/acpi/smi_device_throttle.c | 108 ++++++++++++++++++++ + drivers/acpi/smi_thermal.c | 193 ++++++++++++++++++++++++++++++++++++ + include/linux/smi_thermal.h | 60 +++++++++++ + 5 files changed, 376 insertions(+), 0 deletions(-) + create mode 100644 drivers/acpi/smi_device_throttle.c + create mode 100644 drivers/acpi/smi_thermal.c + create mode 100644 include/linux/smi_thermal.h + +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index c8f50c0..2f65654 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -189,6 +189,19 @@ config THERMAL_SENSOR + help + This driver adds support for AUX trip programming of sensors withing ACPI thermal zones. This is an intel platform specific driver. + ++config SMI_THERMAL ++ tristate "SMI Thermal driver" ++ depends on ACPI_THERMAL ++ default y ++ help ++ This driver adds support for AUX trip programming of sensors withing ACPI thermal zones. This is an intel platform specific driver. ++ ++config SMI_DEVICE_THROTTLE ++ tristate "SMI Device Throttle Driver" ++ depends on SMI_THERMAL ++ default y ++ help ++ This driver adds support for throttling of device based on SMI. This is an intel platform specific driver. + + config ACPI_NUMA + bool "NUMA support" +diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile +index 4cda36c..84252a3 100644 +--- a/drivers/acpi/Makefile ++++ b/drivers/acpi/Makefile +@@ -52,7 +52,9 @@ obj-$(CONFIG_ACPI_POWER) += power.o + obj-$(CONFIG_ACPI_PROCESSOR) += processor.o + obj-$(CONFIG_ACPI_CONTAINER) += container.o + obj-$(CONFIG_ACPI_THERMAL) += thermal.o ++obj-$(CONFIG_SMI_THERMAL) += smi_thermal.o + obj-$(CONFIG_THERMAL_SENSOR) += thermal_sensor.o ++obj-$(CONFIG_SMI_DEVICE_THROTTLE)+= smi_device_throttle.o + obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o + obj-$(CONFIG_ACPI_DEBUG) += debug.o + obj-$(CONFIG_ACPI_NUMA) += numa.o +diff --git a/drivers/acpi/smi_device_throttle.c b/drivers/acpi/smi_device_throttle.c +new file mode 100644 +index 0000000..f0d3861 +--- /dev/null ++++ b/drivers/acpi/smi_device_throttle.c +@@ -0,0 +1,108 @@ ++/* ++ * smi_device_throttle.c - SMI Device Throttle Driver ($Revision: 1 $) ++ * ++ * Copyright (C) 2006, 2007 Sujith Thomas ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ * ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Sujith Thomas"); ++MODULE_DESCRIPTION("SMI throttle driver"); ++MODULE_LICENSE("GPL"); ++ ++/*No:of devices using SMI interface for throttling*/ ++#define SMI_THERMAL_DEVICE_COUNT 1 ++ ++/*Port and data associated with each device*/ ++static struct smi_thermal_info smi_thermal_device_info[SMI_THERMAL_DEVICE_COUNT] ++ = { ++ {.name = "MEM0", ++ .cmdport = 0xB2, ++ .dataport = 0xB3, ++ .setthrottlelimit = 0xDC, ++ .getthrottlelimit = 0xDD, ++ .getmaxthrottle = 0xDD, ++ .maxdat = 0x00, ++ .getdat = 0x01, ++ .caps = DEVICE_CAPS_SW_PGM_THERMAL_EVENTS, ++ .td = NULL, ++ .driver = { ++ .class = THERMAL_MEM_CLASS, ++ .ops = NULL, ++ }, ++ }, ++}; ++static int __init smi_devices_init(void) ++{ ++ int result = 0; ++ int i; ++ struct thermal_device_ops *ops; ++ ++ /*Query the ops interface from smi thermal driver*/ ++ ops = smi_get_thermalops(); ++ if (!ops) ++ return -EINVAL; ++ for (i = 0; i < SMI_THERMAL_DEVICE_COUNT; i++) { ++ smi_thermal_device_info[i].driver.ops = ops; ++ ++ /*Register component driver with thermal zone driver*/ ++ result = ++ thermal_register_device_driver(&smi_thermal_device_info[i]. ++ driver); ++ if (result) { ++ return result; ++ } ++ /*Register singleton device with thermal zone driver*/ ++ if (NULL == ++ (smi_thermal_device_info[i].td = ++ thermal_register_device(smi_thermal_device_info[i]. ++ name, ++ smi_thermal_device_info[i]. ++ driver.class, ++ &smi_thermal_device_info[i]))) { ++ return -EFAULT; ++ } ++ if (result) { ++ thermal_unregister_device_driver ++ (&smi_thermal_device_info[i].driver); ++ return result; ++ } ++ } ++ return 0; ++} ++static void __exit smi_devices_exit(void) ++{ ++ int i; ++ for (i = 0; i < SMI_THERMAL_DEVICE_COUNT; i++) { ++ thermal_unregister_device(smi_thermal_device_info[i].td); ++ thermal_unregister_device_driver(&smi_thermal_device_info[i]. ++ driver); ++ } ++} ++ ++module_init(smi_devices_init); ++module_exit(smi_devices_exit); ++MODULE_ALIAS("smi_device_throttle"); +diff --git a/drivers/acpi/smi_thermal.c b/drivers/acpi/smi_thermal.c +new file mode 100644 +index 0000000..21e8e30 +--- /dev/null ++++ b/drivers/acpi/smi_thermal.c +@@ -0,0 +1,193 @@ ++/* ++ * smi_thermal.c - SMI thermal Driver ($Revision: 1 $) ++ * ++ * Copyright (C) 2006, 2007 Sujith Thomas ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ * ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Sujith Thomas"); ++MODULE_DESCRIPTION("SMI Device Throttle Driver"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * getmaxthrottlestate ++ * ----------------------------- ++ * call back function for getting the device's maximum throttle limit ++ * sinfo : smi_thermal_info ++ */ ++static int get_max_throttle_limit(struct smi_thermal_info *sinfo) ++{ ++ int maxthrottlestate; ++ ++ outb(sinfo->maxdat, sinfo->dataport); ++ outb(sinfo->getmaxthrottle, sinfo->cmdport); ++ msleep(100); ++ maxthrottlestate = inb(sinfo->dataport); ++ ++ return maxthrottlestate; ++} ++ ++/* ++ * smi_thermal_device_get_throttle_limit ++ * ----------------------------- ++ * call back function for getting the device's current throttle limit ++ * data : smi_thermal_info ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int smi_thermal_device_get_throttle_limit(void *data, char *buf) ++{ ++ char *s = buf; ++ int throttlevalue = 0; ++ ++ struct smi_thermal_info *sinfo = (struct smi_thermal_info *)data; ++ ++ if (!buf || !data) ++ return -EINVAL; ++ ++ /*Read the value*/ ++ outb(sinfo->getdat, sinfo->dataport); ++ outb(sinfo->getthrottlelimit, sinfo->cmdport); ++ msleep(100); ++ throttlevalue = inb(sinfo->dataport); ++ ++ s += sprintf(s, "%d\n", throttlevalue); ++ ++ return 0; ++} ++ ++/* ++ * smi_thermal_device_set_throttle_limit ++ * ----------------------------- ++ * call back function for setting the device's new throttle limit ++ * data : smi_thermal_info ++ * buf : sysfs buffer that contains the new value ++ */ ++static int smi_thermal_device_set_throttle_limit(enum throttle_set_type type, ++ void *data, const char *buf) ++{ ++ int new_state = 0; ++ int maxthrottlestate = 0; ++ ++ struct smi_thermal_info *sinfo = (struct smi_thermal_info *)data; ++ ++ if (!buf || !data) ++ return -EINVAL; ++ ++ /*Only absolute value throttling is supported for time being*/ ++ if (THROTTLE_ABS != type) ++ return -EINVAL; ++ ++ maxthrottlestate = get_max_throttle_limit(sinfo); ++ new_state = simple_strtol(buf, NULL, 0); ++ ++ /* we need to check if state is <= max */ ++ if (new_state >= maxthrottlestate || new_state < 0) { ++ return -EINVAL; ++ } ++ /*Write new value*/ ++ outb(new_state, sinfo->dataport); ++ outb(sinfo->setthrottlelimit, sinfo->cmdport); ++ ++ return 0; ++} ++ ++/* ++ * smi_thermal_device_get_throttle_limit ++ * ----------------------------- ++ * call back function for getting the device's maximum throttle limit ++ * data : smi_thermal_info ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int smi_thermal_device_get_maxthrottle_limit(void *data, char *buf) ++{ ++ int maxthrottlestate = 0; ++ char *s = buf; ++ struct smi_thermal_info *sinfo = (struct smi_thermal_info *)data; ++ ++ if (!buf || !data) ++ return -EINVAL; ++ ++ maxthrottlestate = get_max_throttle_limit(sinfo); ++ ++ s += sprintf(s, "%d\n", maxthrottlestate); ++ ++ return (s - buf); ++} ++ ++/* ++ * smi_thermal_device_get_caps ++ * ----------------------------- ++ * call back function for getting the device's capabilities ++ * data : smi_thermal_info ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int smi_thermal_device_get_caps(void *data, char *buf) ++{ ++ char *s = buf; ++ struct smi_thermal_info *sinfo = NULL; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ sinfo = (struct smi_thermal_info *)data; ++ ++ s += sprintf(buf, "%lu \n", sinfo->caps); ++ ++ return (s - buf); ++} ++ ++static struct thermal_device_ops smi_thermal_ops = { ++ .getthrottlelimit = smi_thermal_device_get_throttle_limit, ++ .setthrottlelimit = smi_thermal_device_set_throttle_limit, ++ .getmaxthrottlelimit = smi_thermal_device_get_maxthrottle_limit, ++ .getcaps = smi_thermal_device_get_caps, ++}; ++ ++/* ++ * smi_get_thermalops ++ * ------------------- ++ * Interface for other drivers which uses SMI for throttling ++ */ ++struct thermal_device_ops *smi_get_thermalops(void) ++{ ++ return &smi_thermal_ops; ++} ++EXPORT_SYMBOL(smi_get_thermalops); ++ ++static int __init smi_thermal_init(void) ++{ ++ return 0; ++} ++ ++static void __exit smi_thermal_exit(void) ++{ ++ ++} ++ ++module_init(smi_thermal_init); ++module_exit(smi_thermal_exit); ++ ++MODULE_ALIAS("smi_thermal"); +diff --git a/include/linux/smi_thermal.h b/include/linux/smi_thermal.h +new file mode 100644 +index 0000000..ba428ad +--- /dev/null ++++ b/include/linux/smi_thermal.h +@@ -0,0 +1,60 @@ ++/* ++* smi_thermal.h - Generic smi driver for thermal extensions ($Revision: 1 $) ++* ++* Copyright (C) 2006, 2007 Sujith Thomas ++* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++* ++* This program is free software; you can redistribute it and/or modify ++* it under the terms of the GNU General Public License as published by ++* the Free Software Foundation; version 2 of the License. ++* ++* This program is distributed in the hope that it will be useful, but ++* WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++* General Public License for more details. ++* ++* You should have received a copy of the GNU General Public License along ++* with this program; if not, write to the Free Software Foundation, Inc., ++* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++* ++* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++* ++* ++* ++*/ ++ ++#include ++ ++#define SMI_MAX_THROTTLE_LIMIT 8 ++ ++struct smi_thermal_info { ++ /*ACPI device name (eg:- TZ00)*/ ++ char name[ACPI_MAX_CHAR]; ++ /*Command port for SMI driver*/ ++ unsigned int cmdport; ++ /*Data port for SMI driver*/ ++ unsigned int dataport; ++ /*Command code for set new throttle limit*/ ++ unsigned int setthrottlelimit; ++ /*Command code for get current throttle limit*/ ++ unsigned int getthrottlelimit; ++ /*Command code for get max throttle limit*/ ++ unsigned int getmaxthrottle; ++ /*Argument passed for getting max throttle limit*/ ++ unsigned int maxdat; ++ /*Argument passed for getting current throttle limit*/ ++ unsigned int getdat; ++ ++ /*Device capabilities*/ ++ unsigned long caps; ++ struct thermal_device *td; ++ struct thermal_device_driver driver; ++}; ++ ++/* ++ * smi_get_thermalops ++ * ------------------- ++ * Interface for other drivers which uses SMI for throttling ++ * for getting the callback functions ++ */ ++struct thermal_device_ops *smi_get_thermalops(void); +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0002-Thermal-Poulsbo-cpufreq-changes-to-change-p-states.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0002-Thermal-Poulsbo-cpufreq-changes-to-change-p-states.patch @@ -0,0 +1,75 @@ +From 6376d8703c8b5b4e70595b6444b4a91d8f9ca3a4 Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: cpufreq changes to change p-states + +-Bring back the cpufreq_set_policy so that acpi_processor driver +can change P-states + +Signed-off-by: Sujith Thomas +--- + drivers/cpufreq/cpufreq.c | 35 +++++++++++++++++++++++++++++++++++ + include/linux/cpufreq.h | 1 + + 2 files changed, 36 insertions(+), 0 deletions(-) + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index eb37fba..12b6591 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1626,6 +1626,41 @@ error_out: + } + + /** ++ * cpufreq_set_policy - set a new CPUFreq policy ++ * @policy: policy to be set. ++ * ++ * Sets a new CPU frequency and voltage scaling policy. ++ */ ++int cpufreq_set_policy(struct cpufreq_policy *policy) ++{ ++ int ret = 0; ++ struct cpufreq_policy *data; ++ if (!policy) ++ return -EINVAL; ++ ++ data = cpufreq_cpu_get(policy->cpu); ++ if (!data) ++ return -EINVAL; ++ ++ if (unlikely(lock_policy_rwsem_write(policy->cpu))) ++ return -EINVAL; ++ ++ ret = __cpufreq_set_policy(data, policy); ++ ++ data->user_policy.min = data->min; ++ data->user_policy.max = data->max; ++ data->user_policy.policy = data->policy; ++ data->user_policy.governor = data->governor; ++ ++ unlock_policy_rwsem_write(policy->cpu); ++ ++ cpufreq_cpu_put(data); ++ ++ return ret; ++} ++EXPORT_SYMBOL(cpufreq_set_policy); ++ ++/** + * cpufreq_update_policy - re-evaluate an existing cpufreq policy + * @cpu: CPU which shall be re-evaluated + * +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index 963051a..0402023 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -266,6 +266,7 @@ struct freq_attr { + * CPUFREQ 2.6. INTERFACE * + *********************************************************************/ + int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); ++int cpufreq_set_policy(struct cpufreq_policy *policy); + int cpufreq_update_policy(unsigned int cpu); + + +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/patchset/0004-Thermal-Poulsbo-Register-LCD-with-thermal.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/patchset/0004-Thermal-Poulsbo-Register-LCD-with-thermal.patch @@ -0,0 +1,218 @@ +From d16d0dd90891aee036f4d2afafc8f9f085d04629 Mon Sep 17 00:00:00 2001 +From: Sujith Thomas +Date: Tue, 14 Aug 2007 16:23:56 +0800 +Subject: [PATCH] Poulsbo: Register LCD with thermal + +-Register/Unregister with ACPI thermal driver +-Exports the callbacks for switching LCD brightness + +Signed-off-by: Sujith Thomas +--- + drivers/acpi/Kconfig | 2 +- + drivers/acpi/video.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 129 insertions(+), 1 deletions(-) + +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index 07ae366..ad9f836 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -155,7 +155,7 @@ config ACPI_THERMAL + + config ACPI_VIDEO + tristate "Video" +- depends on X86 && BACKLIGHT_CLASS_DEVICE ++ depends on X86 && BACKLIGHT_CLASS_DEVICE && ACPI_THERMAL + default n + help + This driver implement the ACPI Extensions For Display Adapters +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index 00d25b3..bdb67b8 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -38,6 +38,8 @@ + #include + #include + ++#include ++ + #define ACPI_VIDEO_COMPONENT 0x08000000 + #define ACPI_VIDEO_CLASS "video" + #define ACPI_VIDEO_BUS_NAME "Video Bus" +@@ -162,6 +164,7 @@ struct acpi_video_device_brightness { + + struct acpi_video_device { + unsigned long device_id; ++ acpi_bus_id name; + struct acpi_video_device_flags flags; + struct acpi_video_device_cap cap; + struct list_head entry; +@@ -169,6 +172,7 @@ struct acpi_video_device { + struct acpi_device *dev; + struct acpi_video_device_brightness *brightness; + struct backlight_device *backlight; ++ struct thermal_device *td; + }; + + /* bus */ +@@ -1356,6 +1360,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device, + break; + case ACPI_VIDEO_DISPLAY_LCD: + data->flags.lcd = 1; ++ data->td = ++ thermal_register_device(device->pnp.bus_id, ++ THERMAL_LCD_CLASS, ++ data); + break; + default: + data->flags.unknown = 1; +@@ -1665,6 +1673,9 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) + up(&video->sem); + acpi_video_device_remove_fs(device->dev); + ++ if (device->flags.lcd) ++ thermal_unregister_device(device->td); ++ + status = acpi_remove_notify_handler(device->dev->handle, + ACPI_DEVICE_NOTIFY, + acpi_video_device_notify); +@@ -1870,6 +1881,119 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) + return 0; + } + ++/* -------------------------------------------------------------------------- ++ Thermal management callbacks ++ -------------------------------------------------------------------------- */ ++ ++/* ++ * lcd_device_get_throttle_limit ++ * ----------------------------- ++ * call back function for getting the device's current throttle limit ++ * data : acpi_video_device ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int lcd_device_get_throttle_limit(void *data, char *buf) ++{ ++ struct acpi_video_device *vd; ++ char *s = buf; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ vd = (struct acpi_video_device *)data; ++ s += sprintf(buf, "%d\n", vd->brightness->curr); ++ ++ return (s - buf); ++} ++ ++/* ++ * lcd_device_set_throttle_limit ++ * ----------------------------- ++ * call back function for setting the device's new throttle limit ++ * data : acpi_video_device ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int lcd_device_set_throttle_limit(enum throttle_set_type type, ++ void *data, const char *buf) ++{ ++ int new_state; ++ struct acpi_video_device *vd; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ /*Only absolute value throttling is supported for time being*/ ++ if (THROTTLE_ABS != type) ++ return -EINVAL; ++ ++ vd = (struct acpi_video_device *)data; ++ new_state = simple_strtol(buf, NULL, 0); ++ if (new_state == vd->brightness->curr ++ || new_state > vd->brightness->count || new_state < 0) ++ return 0; ++ ++ if (ACPI_SUCCESS ++ (acpi_video_device_lcd_set_level ++ (vd, vd->brightness->levels[new_state]))) ++ vd->brightness->curr = new_state; ++ ++ return 0; ++} ++ ++/* ++ * lcd_device_get_maxthrottle_limit ++ * ----------------------------- ++ * call back function for getting the device's maximum throttle limit ++ * data : acpi_video_device ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int lcd_device_get_maxthrottle_limit(void *data, char *buf) ++{ ++ struct acpi_video_device *vd; ++ char *s = buf; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ vd = (struct acpi_video_device *)data; ++ s += sprintf(buf, "%d\n", vd->brightness->count); ++ ++ return (s - buf); ++} ++ ++/* ++ * lcd_device_get_caps ++ * ----------------------------- ++ * call back function for getting the device's capabilities ++ * data : acpi_video_device ++ * buf : sysfs buffer that needs to be filled back ++ */ ++static int lcd_device_get_caps(void *data, char *buf) ++{ ++ char *s = buf; ++ unsigned int caps = 0; ++ ++ if (NULL == data || NULL == buf) ++ return -EINVAL; ++ ++ caps |= DEVICE_CAPS_SW_PGM_THERMAL_EVENTS; ++ s += sprintf(buf, "%d\n", caps); ++ ++ return (s - buf); ++} ++ ++static struct thermal_device_ops lcd_thermal_ops = { ++ .getthrottlelimit = lcd_device_get_throttle_limit, ++ .setthrottlelimit = lcd_device_set_throttle_limit, ++ .getmaxthrottlelimit = lcd_device_get_maxthrottle_limit, ++ .getcaps = lcd_device_get_caps, ++}; ++ ++static struct thermal_device_driver lcd_thermal_driver = { ++ .class = THERMAL_LCD_CLASS, ++ .ops = &lcd_thermal_ops ++}; ++ + static int __init acpi_video_init(void) + { + int result = 0; +@@ -1885,6 +2009,8 @@ static int __init acpi_video_init(void) + return -ENODEV; + acpi_video_dir->owner = THIS_MODULE; + ++ thermal_register_device_driver(&lcd_thermal_driver); ++ + result = acpi_bus_register_driver(&acpi_video_bus); + if (result < 0) { + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); +@@ -1899,6 +2025,8 @@ static void __exit acpi_video_exit(void) + + acpi_bus_unregister_driver(&acpi_video_bus); + ++ thermal_unregister_device_driver(&lcd_thermal_driver); ++ + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); + + return; +-- +1.5.2.4 + --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/config.i386 +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/config.i386 @@ -0,0 +1,2400 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_4KSTACKS is not set +CONFIG_AC97_BUS=m +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BAY=m +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=m +CONFIG_ACPI_EC=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_POWER=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SLEEP_PROC_FS=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_INTEL=m +CONFIG_AIRO=m +CONFIG_ALI_FIR=m +CONFIG_ANON_INODES=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_ARPD is not set +CONFIG_ATA=m +CONFIG_ATALK=m +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=m +CONFIG_ATMEL=m +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BCM43XX=m +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_BCM43XX_PIO=y +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDE=m +CONFIG_BLK_DEV_IDEACPI=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDEDISK=m +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SVWKS is not set +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_UMEM=m +CONFIG_BLK_DEV_XD=m +CONFIG_BLOCK=y +CONFIG_BONDING=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CHR_DEV_SG=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_COMPAT_VDSO=y +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_COPS=m +CONFIG_COPS_DAYNA=y +CONFIG_COPS_TANGENT=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=m +CONFIG_CRAMFS=y +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ABLKCIPHER=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CS5535_GPIO=m +CONFIG_DAB=y +CONFIG_DAVICOM_PHY=m +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DMI=y +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DOUBLEFAULT=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CORE_ATTACH=y +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TDA827X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_MT2060=m +CONFIG_DVB_TUNER_QT1010=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +CONFIG_E100=m +CONFIG_E1000=m +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +CONFIG_E1000_NAPI=y +CONFIG_EARLY_PRINTK=y +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_EDAC=m +# CONFIG_EDAC_AMD76X is not set +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_POLL=y +CONFIG_EDAC_R82600=m +# CONFIG_EDD is not set +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_ELF_CORE=y +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_EPOLL=y +CONFIG_ESI_DONGLE=m +# CONFIG_ESPSERIAL is not set +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_IMSTT is not set +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_VESA is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIXED_MII_100_FDX is not set +# CONFIG_FIXED_MII_10_FDX is not set +CONFIG_FIXED_PHY=m +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +# CONFIG_FORCED_INLINING is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_FTL=m +CONFIG_FUSE_FS=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_TIME=y +CONFIG_GIRBIL_DONGLE=m +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_HERMES=m +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_FF is not set +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +# CONFIG_HPET_RTC_IRQ is not set +CONFIG_HPET_TIMER=y +CONFIG_HT_IRQ=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_VIA=m +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_IDE=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDE_GENERIC=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP is not set +CONFIG_IP_SCTP=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISA_DMA_API=y +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +CONFIG_KTIME_SCALAR=y +CONFIG_LAPB=m +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOGO is not set +# CONFIG_LSF is not set +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +# CONFIG_M386 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUG is not set +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_PNC2000=m +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_ETHERNET=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NEW_LEDS=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NR_QUICK=1 +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NVRAM=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OPROFILE=m +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PC8736x_GPIO=m +CONFIG_PCI=y +CONFIG_PCI_ATMEL=m +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +CONFIG_PCI_MMCONFIG=y +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +CONFIG_PLIST=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TRACE=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +# CONFIG_PNP_DEBUG is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRISM54=m +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QSEMI_PHY=m +CONFIG_QUICKLIST=y +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +# CONFIG_RADIO_TYPHOON_PROC_FS is not set +CONFIG_RADIO_ZOLTRIX=m +CONFIG_RAID_ATTRS=m +CONFIG_RAMFS=y +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RTC_CLASS=m +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=m +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_SATA_AHCI=m +# CONFIG_SCHEDSTATS is not set +CONFIG_SCSI=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCx200_ACB=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_CAPABILITIES=m +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_ROOTPLUG=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +# CONFIG_SK98LIN is not set +# CONFIG_SLAB is not set +CONFIG_SLHC=m +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_HWDEP=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RTCTIMER=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOUND=m +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SSFDC=m +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_STANDALONE=y +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_SWAP=y +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +# CONFIG_TASKSTATS is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +CONFIG_TEKRAM_DONGLE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIMERFD=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TUN=m +CONFIG_TUNER_3036=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_CATC=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA2XX is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HIDINPUT_POWERBOOK=y +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_NET2280=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SN9C102=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="Unofficial" +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_DPC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_MSP3400=m +# CONFIG_VIDEO_MXB is not set +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_24XXX=y +CONFIG_VIDEO_PVRUSB2_29XXX=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SAA7191=m +CONFIG_VIDEO_SELECT=y +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VITESSE_PHY=m +CONFIG_VLSI_FIR=m +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN_ROUTER=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS_EXT=y +CONFIG_WLAN_80211=y +CONFIG_X25=m +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_MODEL=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +# CONFIG_X86_NUMAQ is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +# CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI is not set +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_VISWS is not set +# CONFIG_X86_VOYAGER is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 +# +# Config options for config.ume automatically generated by splitconfig.pl +# +# CONFIG_60XX_WDT is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_9P_FS is not set +# CONFIG_AC3200 is not set +# CONFIG_ACENIC is not set +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_AGP_ALI is not set +# CONFIG_AGP_AMD is not set +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_ATI is not set +# CONFIG_AGP_EFFICEON is not set +# CONFIG_AGP_NVIDIA is not set +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_SWORKS is not set +# CONFIG_AGP_VIA is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APM is not set +# CONFIG_APPLICOM is not set +# CONFIG_APRICOT is not set +# CONFIG_ARCNET is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_AT1700 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATM is not set +# CONFIG_AUDIT is not set +# CONFIG_B44 is not set +# CONFIG_BACKLIGHT_PROGEAR is not set +CONFIG_BCM43XX_DEBUG=y +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +CONFIG_BLK_DEV_PIIX=m +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BNX2 is not set +# CONFIG_BRIDGE is not set +# CONFIG_CASSINI is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CODA_FS is not set +# CONFIG_COMPUTONE is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_CPUSETS is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_CS89x0 is not set +# CONFIG_CYCLADES is not set +# CONFIG_DCDBAS is not set +# CONFIG_DECNET is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DELL_RBU is not set +# CONFIG_DEPCA is not set +# CONFIG_DGRS is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DL2K is not set +# CONFIG_DMA_ENGINE is not set +# CONFIG_DRM is not set +# CONFIG_DTLK is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EFI is not set +# CONFIG_EFS_FS is not set +# CONFIG_EPIC100 is not set +# CONFIG_EQUALIZER is not set +# CONFIG_ES3210 is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_CYBLA is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_HECUBA is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +# CONFIG_FORCEDETH is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set +# CONFIG_FUSION_SPI is not set +CONFIG_GENERIC_PENDING_IRQ=y +# CONFIG_GFS2_FS is not set +# CONFIG_HAMACHI is not set +# CONFIG_HAMRADIO is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIPPI is not set +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set +CONFIG_HOTPLUG_CPU=y +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HP100 is not set +CONFIG_HPET_EMULATE_RTC=y +# CONFIG_HPFS_FS is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_I2C_POULSBO=m +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8K is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_IBM_ASM is not set +# CONFIG_INFINIBAND is not set +CONFIG_INPUT_YEALINK=m +# CONFIG_IPC_NS is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPX is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_IP_VS is not set +CONFIG_IRQBALANCE=y +# CONFIG_ISAPNP is not set +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISDN is not set +# CONFIG_ITCO_WDT is not set +# CONFIG_IXGB is not set +# CONFIG_JFS_FS is not set +# CONFIG_KEXEC is not set +# CONFIG_KS0108 is not set +# CONFIG_KVM is not set +# CONFIG_LANCE is not set +# CONFIG_LBD is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_LNE390 is not set +CONFIG_LOCK_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M686 is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_MACINTOSH_DRIVERS is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_MCA is not set +# CONFIG_MD is not set +# CONFIG_MDA_CONSOLE is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MMC is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO_NEW is not set +# CONFIG_MSI_LAPTOP is not set +CONFIG_MSS=m +CONFIG_MSS_BLOCK=m +CONFIG_MSS_SDHCI=m +# CONFIG_MWAVE is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NATSEMI is not set +# CONFIG_NCP_FS is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_POCKET is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NFSD is not set +CONFIG_NORTEL_HERMES=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=8 +# CONFIG_NS83820 is not set +# CONFIG_N_HDLC is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_PARAVIRT is not set +# CONFIG_PARTITION_ADVANCED is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PC87413_WDT is not set +# CONFIG_PCCARD is not set +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCIPCWATCHDOG is not set +CONFIG_PCI_HERMES=m +# CONFIG_PCI_MSI is not set +# CONFIG_PCNET32 is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHONE is not set +# CONFIG_PLIP is not set +CONFIG_PLX_HERMES=m +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_PNPBIOS is not set +# CONFIG_PPDEV is not set +CONFIG_PREEMPT_BKL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PRINTER is not set +# CONFIG_QLA3XXX is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_R3964 is not set +# CONFIG_R8169 is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_RIO is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC=y +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_S2IO is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_SC92031 is not set +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SEAGATE is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCx200 is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SHAPER is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SLIP is not set +# CONFIG_SLUB_DEBUG is not set +CONFIG_SMP=y +# CONFIG_SMSC37B787_WDT is not set +# CONFIG_SND_AC97_POWER_SAVE is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ADLIB is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_DT019X is not set +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_MIRO is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MTS64 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_PORTMAN2X4 is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SOC is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SONYPI is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPECIALIX is not set +CONFIG_SPI_SPIDEV=m +# CONFIG_STALDRV is not set +CONFIG_STOP_MACHINE=y +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SUSPEND_SMP=y +# CONFIG_SX is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_SYSV_FS is not set +# CONFIG_TELCLOCK is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_TIGON3 is not set +# CONFIG_TIPAR is not set +# CONFIG_TLAN is not set +CONFIG_TMD_HERMES=m +# CONFIG_TOSHIBA is not set +# CONFIG_TR is not set +# CONFIG_UFS_FS is not set +# CONFIG_UID16 is not set +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_U132_HCD is not set +# CONFIG_UTS_NS is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VLAN_8021Q is not set +CONFIG_VM86=y +# CONFIG_VXFS_FS is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83697HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_WAN is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WRAPPER_PRINT=y +CONFIG_X86_ALIGNMENT_16=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_F00F_BUG=y +# CONFIG_X86_GX_SUSPMOD is not set +CONFIG_X86_HT=y +# CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_LONGRUN is not set +# CONFIG_X86_P4_CLOCKMOD is not set +# CONFIG_X86_POWERNOW_K6 is not set +# CONFIG_X86_POWERNOW_K7 is not set +# CONFIG_X86_POWERNOW_K8 is not set +CONFIG_X86_SMP=y +# CONFIG_X86_SPEEDSTEP_SMI is not set +CONFIG_X86_TRAMPOLINE=y +# CONFIG_XFS_FS is not set +# CONFIG_YELLOWFIN is not set +CONFIG_THERMAL_SENSOR=m +CONFIG_SMI_THERMAL=m +CONFIG_SMI_DEVICE_THROTTLE=m +# CONFIG_NIU is not set --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/ume/vars +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/ume/vars @@ -0,0 +1,7 @@ +arch="i386" +supported="UME" +desc="Ubuntu Moblie and Embedded" +target="UME kernel" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, rhcs-modules2-1" +section_image="universe/base" --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/README +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/README @@ -0,0 +1,46 @@ +Welcome to the answer to all your requests. + +The binary-custom target for the kernel allows easy building of special +kernels that would otherwise not be allowed in our tree. The way this is +achieved is to disaccociate the normal build process and patches required +for these kernels. + +In this directory, you will need to create 4 files for your custom +kernel. All files are placed in a subdirectory. This subdirectory is the +name of your flavour (IOW, what will be appended to 2.6.X-ABI- to get the +package name). So the subdirectory name should be package name safe (e.g., +no underscores). There are currently at least three files and one directory +required in each subdirectory: + + FLAV/config.ARCH : The kernel .config used to build the kernel + (one for each architecture this flavour will + build on). + + FLAV/patchset : The directory containing the patchset for this + flavour, to be applied with -p1. + + FLAV/rules : A make file snippet for any target overrides + (usually empty). See below for what can be here. + + FLAV/vars : Template for control file generation. + +The rules file can contain overrides for some variables used during the +build. Here is a list of what can be defined in this make file snippet: + + build_image_FLAV : The image make target (e.g. bzImage). + + kernel_file_FLAV : The resulting kernel image from the build. + +The patchset directory contains a series of patches, named using a convention +such as -.patch. e.g. 0001-foo.patch, 0002-bar.patch. The +patches will then be applied in increasing order by number. + +To add your custom kernel to the normal build, add it to the +custom_flavours var for each architecture it will build on in the +debian/rules.d/ARCH.mk file. + +Once done, you can specifically build the custom image using: + + fakeroot debian/rules custom-binary-FLAV + +That's it! --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/rt/rules +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/rt/rules @@ -0,0 +1 @@ +# Nothing special here --- linux-source-2.6.22-2.6.22.orig/debian/binary-custom.d/rt/patchset/001.patch +++ linux-source-2.6.22-2.6.22/debian/binary-custom.d/rt/patchset/001.patch @@ -0,0 +1,60856 @@ +diff -Nur custom-source-rt.orig/Documentation/cpuidle/core.txt custom-source-rt/Documentation/cpuidle/core.txt +--- custom-source-rt.orig/Documentation/cpuidle/core.txt 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/Documentation/cpuidle/core.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,17 @@ ++ ++ Supporting multiple CPU idle levels in kernel ++ ++ cpuidle ++ ++General Information: ++ ++Various CPUs today support multiple idle levels that are differentiated ++by varying exit latencies and power consumption during idle. ++cpuidle is a generic in-kernel infrastructure that separates ++idle policy (governor) from idle mechanism (driver) and provides a ++standardized infrastructure to support independent development of ++governors and drivers. ++ ++cpuidle resides under drivers/cpuidle. ++ ++ +diff -Nur custom-source-rt.orig/Documentation/cpuidle/driver.txt custom-source-rt/Documentation/cpuidle/driver.txt +--- custom-source-rt.orig/Documentation/cpuidle/driver.txt 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/Documentation/cpuidle/driver.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,29 @@ ++ ++ ++ Supporting multiple CPU idle levels in kernel ++ ++ cpuidle drivers ++ ++ ++ ++ ++cpuidle driver hooks into the cpuidle infrastructure and does the ++architecture/platform dependent part of CPU idle states. Driver ++provides the platform idle state detection capability and also ++has mechanisms in place to support actusl entry-exit into a CPU idle state. ++ ++cpuidle driver supports capability detection for a platform using the ++init and exit routines. They will be called for each online CPU, with a ++percpu cpuidle_driver object and driver should fill in cpuidle_states ++inside cpuidle_driver depending on the CPU capability. ++ ++Driver can handle dynamic state changes (like battery<->AC), by calling ++force_redetect interface. ++ ++It is possible to have more than one driver registered at the same time and ++user can switch between drivers using /sysfs interface (when enabled). ++ ++Interfaces: ++int cpuidle_register_driver(struct cpuidle_driver *drv); ++void cpuidle_unregister_driver(struct cpuidle_driver *drv); ++int cpuidle_force_redetect(struct cpuidle_device *dev); +diff -Nur custom-source-rt.orig/Documentation/cpuidle/governor.txt custom-source-rt/Documentation/cpuidle/governor.txt +--- custom-source-rt.orig/Documentation/cpuidle/governor.txt 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/Documentation/cpuidle/governor.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,28 @@ ++ ++ ++ ++ Supporting multiple CPU idle levels in kernel ++ ++ cpuidle governors ++ ++ ++ ++ ++cpuidle governor is policy routine that decides what idle state to enter at ++any given time. cpuidle core uses different callbacks to governor while ++handling idle entry. ++* select_state() callback where governor can determine next idle state to enter ++* prepare_idle() callback is called before entering an idle state ++* scan() callback is called after a driver forces redetection of the states ++ ++More than one governor can be registered at the same time and ++user can switch between drivers using /sysfs interface (when supported). ++ ++More than one governor part is supported for developers to easily experiment ++with different governors. By default, most optimal governor based on your ++kernel configuration and platform will be selected by cpuidle. ++ ++Interfaces: ++int cpuidle_register_governor(struct cpuidle_governor *gov); ++void cpuidle_unregister_governor(struct cpuidle_governor *gov); ++ +diff -Nur custom-source-rt.orig/Documentation/cpuidle/sysfs.txt custom-source-rt/Documentation/cpuidle/sysfs.txt +--- custom-source-rt.orig/Documentation/cpuidle/sysfs.txt 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/Documentation/cpuidle/sysfs.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,35 @@ ++ ++ ++ Supporting multiple CPU idle levels in kernel ++ ++ cpuidle sysfs ++ ++System global cpuidle related information and tunables are under ++/sys/devices/system/cpu/cpuidle ++ ++The current interfaces in this directory has self-explanatory names: ++* current_driver_ro ++* current_governor_ro ++ ++With cpuidle_sysfs_switch boot option (meant for developer testing) ++following objects are visible instead. ++* available_drivers ++* available_governors ++* current_driver ++* current_governor ++In this case user can switch the driver, governor at run time by writing ++onto current_driver and current_governor. ++ ++ ++Per logical CPU specific cpuidle information are under ++/sys/devices/system/cpu/cpuX/cpuidle ++for each online cpu X ++ ++Under this percpu directory, there is a directory for each idle state supported ++by the driver, which in turn has ++* latency : Latency to exit out of this idle state (in microseconds) ++* power : Power consumed while in this idle state (in milliwatts) ++* time : Total time spent in this idle state (in microseconds) ++* usage : Number of times this state was entered (count) ++ ++ +diff -Nur custom-source-rt.orig/Documentation/kernel-parameters.txt custom-source-rt/Documentation/kernel-parameters.txt +--- custom-source-rt.orig/Documentation/kernel-parameters.txt 2007-10-02 17:10:22.000000000 +0000 ++++ custom-source-rt/Documentation/kernel-parameters.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -1009,49 +1009,6 @@ + + mga= [HW,DRM] + +- migration_cost= +- [KNL,SMP] debug: override scheduler migration costs +- Format: ,,... +- This debugging option can be used to override the +- default scheduler migration cost matrix. The numbers +- are indexed by 'CPU domain distance'. +- E.g. migration_cost=1000,2000,3000 on an SMT NUMA +- box will set up an intra-core migration cost of +- 1 msec, an inter-core migration cost of 2 msecs, +- and an inter-node migration cost of 3 msecs. +- +- WARNING: using the wrong values here can break +- scheduler performance, so it's only for scheduler +- development purposes, not production environments. +- +- migration_debug= +- [KNL,SMP] migration cost auto-detect verbosity +- Format=<0|1|2> +- If a system's migration matrix reported at bootup +- seems erroneous then this option can be used to +- increase verbosity of the detection process. +- We default to 0 (no extra messages), 1 will print +- some more information, and 2 will be really +- verbose (probably only useful if you also have a +- serial console attached to the system). +- +- migration_factor= +- [KNL,SMP] multiply/divide migration costs by a factor +- Format= +- This debug option can be used to proportionally +- increase or decrease the auto-detected migration +- costs for all entries of the migration matrix. +- E.g. migration_factor=150 will increase migration +- costs by 50%. (and thus the scheduler will be less +- eager migrating cache-hot tasks) +- migration_factor=80 will decrease migration costs +- by 20%. (thus the scheduler will be more eager to +- migrate tasks) +- +- WARNING: using the wrong values here can break +- scheduler performance, so it's only for scheduler +- development purposes, not production environments. +- + mousedev.tap_time= + [MOUSE] Maximum time between finger touching and + leaving touchpad surface for touch to be considered +diff -Nur custom-source-rt.orig/Documentation/sched-design-CFS.txt custom-source-rt/Documentation/sched-design-CFS.txt +--- custom-source-rt.orig/Documentation/sched-design-CFS.txt 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/Documentation/sched-design-CFS.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,119 @@ ++ ++This is the CFS scheduler. ++ ++80% of CFS's design can be summed up in a single sentence: CFS basically ++models an "ideal, precise multi-tasking CPU" on real hardware. ++ ++"Ideal multi-tasking CPU" is a (non-existent :-)) CPU that has 100% ++physical power and which can run each task at precise equal speed, in ++parallel, each at 1/nr_running speed. For example: if there are 2 tasks ++running then it runs each at 50% physical power - totally in parallel. ++ ++On real hardware, we can run only a single task at once, so while that ++one task runs, the other tasks that are waiting for the CPU are at a ++disadvantage - the current task gets an unfair amount of CPU time. In ++CFS this fairness imbalance is expressed and tracked via the per-task ++p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of ++time the task should now run on the CPU for it to become completely fair ++and balanced. ++ ++( small detail: on 'ideal' hardware, the p->wait_runtime value would ++ always be zero - no task would ever get 'out of balance' from the ++ 'ideal' share of CPU time. ) ++ ++CFS's task picking logic is based on this p->wait_runtime value and it ++is thus very simple: it always tries to run the task with the largest ++p->wait_runtime value. In other words, CFS tries to run the task with ++the 'gravest need' for more CPU time. So CFS always tries to split up ++CPU time between runnable tasks as close to 'ideal multitasking ++hardware' as possible. ++ ++Most of the rest of CFS's design just falls out of this really simple ++concept, with a few add-on embellishments like nice levels, ++multiprocessing and various algorithm variants to recognize sleepers. ++ ++In practice it works like this: the system runs a task a bit, and when ++the task schedules (or a scheduler tick happens) the task's CPU usage is ++'accounted for': the (small) time it just spent using the physical CPU ++is deducted from p->wait_runtime. [minus the 'fair share' it would have ++gotten anyway]. Once p->wait_runtime gets low enough so that another ++task becomes the 'leftmost task' of the time-ordered rbtree it maintains ++(plus a small amount of 'granularity' distance relative to the leftmost ++task so that we do not over-schedule tasks and trash the cache) then the ++new leftmost task is picked and the current task is preempted. ++ ++The rq->fair_clock value tracks the 'CPU time a runnable task would have ++fairly gotten, had it been runnable during that time'. So by using ++rq->fair_clock values we can accurately timestamp and measure the ++'expected CPU time' a task should have gotten. All runnable tasks are ++sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and ++CFS picks the 'leftmost' task and sticks to it. As the system progresses ++forwards, newly woken tasks are put into the tree more and more to the ++right - slowly but surely giving a chance for every task to become the ++'leftmost task' and thus get on the CPU within a deterministic amount of ++time. ++ ++Some implementation details: ++ ++ - the introduction of Scheduling Classes: an extensible hierarchy of ++ scheduler modules. These modules encapsulate scheduling policy ++ details and are handled by the scheduler core without the core ++ code assuming about them too much. ++ ++ - sched_fair.c implements the 'CFS desktop scheduler': it is a ++ replacement for the vanilla scheduler's SCHED_OTHER interactivity ++ code. ++ ++ I'd like to give credit to Con Kolivas for the general approach here: ++ he has proven via RSDL/SD that 'fair scheduling' is possible and that ++ it results in better desktop scheduling. Kudos Con! ++ ++ The CFS patch uses a completely different approach and implementation ++ from RSDL/SD. My goal was to make CFS's interactivity quality exceed ++ that of RSDL/SD, which is a high standard to meet :-) Testing ++ feedback is welcome to decide this one way or another. [ and, in any ++ case, all of SD's logic could be added via a kernel/sched_sd.c module ++ as well, if Con is interested in such an approach. ] ++ ++ CFS's design is quite radical: it does not use runqueues, it uses a ++ time-ordered rbtree to build a 'timeline' of future task execution, ++ and thus has no 'array switch' artifacts (by which both the vanilla ++ scheduler and RSDL/SD are affected). ++ ++ CFS uses nanosecond granularity accounting and does not rely on any ++ jiffies or other HZ detail. Thus the CFS scheduler has no notion of ++ 'timeslices' and has no heuristics whatsoever. There is only one ++ central tunable: ++ ++ /proc/sys/kernel/sched_granularity_ns ++ ++ which can be used to tune the scheduler from 'desktop' (low ++ latencies) to 'server' (good batching) workloads. It defaults to a ++ setting suitable for desktop workloads. SCHED_BATCH is handled by the ++ CFS scheduler module too. ++ ++ Due to its design, the CFS scheduler is not prone to any of the ++ 'attacks' that exist today against the heuristics of the stock ++ scheduler: fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c all ++ work fine and do not impact interactivity and produce the expected ++ behavior. ++ ++ the CFS scheduler has a much stronger handling of nice levels and ++ SCHED_BATCH: both types of workloads should be isolated much more ++ agressively than under the vanilla scheduler. ++ ++ ( another detail: due to nanosec accounting and timeline sorting, ++ sched_yield() support is very simple under CFS, and in fact under ++ CFS sched_yield() behaves much better than under any other ++ scheduler i have tested so far. ) ++ ++ - sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler ++ way than the vanilla scheduler does. It uses 100 runqueues (for all ++ 100 RT priority levels, instead of 140 in the vanilla scheduler) ++ and it needs no expired array. ++ ++ - reworked/sanitized SMP load-balancing: the runqueue-walking ++ assumptions are gone from the load-balancing code now, and ++ iterators of the scheduling modules are used. The balancing code got ++ quite a bit simpler as a result. ++ +diff -Nur custom-source-rt.orig/Documentation/stable_api_nonsense.txt custom-source-rt/Documentation/stable_api_nonsense.txt +--- custom-source-rt.orig/Documentation/stable_api_nonsense.txt 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/Documentation/stable_api_nonsense.txt 2007-10-02 17:31:08.000000000 +0000 +@@ -62,6 +62,9 @@ + - different structures can contain different fields + - Some functions may not be implemented at all, (i.e. some locks + compile away to nothing for non-SMP builds.) ++ - Parameter passing of variables from function to function can be ++ done in different ways (the CONFIG_REGPARM option controls ++ this.) + - Memory within the kernel can be aligned in different ways, + depending on the build options. + - Linux runs on a wide range of different processor architectures. +diff -Nur custom-source-rt.orig/Makefile custom-source-rt/Makefile +--- custom-source-rt.orig/Makefile 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -490,10 +490,14 @@ + + include $(srctree)/arch/$(ARCH)/Makefile + +-ifdef CONFIG_FRAME_POINTER +-CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) ++ifdef CONFIG_MCOUNT ++CFLAGS += -pg -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) + else +-CFLAGS += -fomit-frame-pointer ++ ifdef CONFIG_FRAME_POINTER ++ CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) ++ else ++ CFLAGS += -fomit-frame-pointer ++ endif + endif + + ifdef CONFIG_DEBUG_INFO +diff -Nur custom-source-rt.orig/arch/arm/Kconfig custom-source-rt/arch/arm/Kconfig +--- custom-source-rt.orig/arch/arm/Kconfig 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -33,6 +33,10 @@ + bool + default n + ++config STACKTRACE_SUPPORT ++ bool ++ default y ++ + config MMU + bool + default y +@@ -591,18 +595,7 @@ + accounting to be spread across the timer interval, preventing a + "thundering herd" at every timer tick. + +-config PREEMPT +- bool "Preemptible Kernel (EXPERIMENTAL)" +- depends on EXPERIMENTAL +- help +- This option reduces the latency of the kernel when reacting to +- real-time or interactive events by allowing a low priority process to +- be preempted even if it is in kernel mode executing a system call. +- This allows applications to run more reliably even when the system is +- under load. +- +- Say Y here if you are building a kernel for a desktop, embedded +- or real-time system. Say N if you are unsure. ++source kernel/Kconfig.preempt + + config NO_IDLE_HZ + bool "Dynamic tick timer" +diff -Nur custom-source-rt.orig/arch/arm/boot/compressed/head.S custom-source-rt/arch/arm/boot/compressed/head.S +--- custom-source-rt.orig/arch/arm/boot/compressed/head.S 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/boot/compressed/head.S 2007-10-02 17:31:08.000000000 +0000 +@@ -836,6 +836,18 @@ + mov pc, r10 + #endif + ++#ifdef CONFIG_MCOUNT ++/* CONFIG_MCOUNT causes boot header to be built with -pg requiring this ++ * trampoline ++ */ ++ .text ++ .align 0 ++ .type mcount %function ++ .global mcount ++mcount: ++ mov pc, lr @ just return ++#endif ++ + .ltorg + reloc_end: + +diff -Nur custom-source-rt.orig/arch/arm/common/time-acorn.c custom-source-rt/arch/arm/common/time-acorn.c +--- custom-source-rt.orig/arch/arm/common/time-acorn.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/common/time-acorn.c 2007-10-02 17:31:08.000000000 +0000 +@@ -77,7 +77,7 @@ + + static struct irqaction ioc_timer_irq = { + .name = "timer", +- .flags = IRQF_DISABLED, ++ .flags = IRQF_DISABLED | IRQF_NODELAY, + .handler = ioc_timer_interrupt + }; + +diff -Nur custom-source-rt.orig/arch/arm/kernel/dma.c custom-source-rt/arch/arm/kernel/dma.c +--- custom-source-rt.orig/arch/arm/kernel/dma.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/dma.c 2007-10-02 17:31:08.000000000 +0000 +@@ -20,7 +20,7 @@ + + #include + +-DEFINE_SPINLOCK(dma_spin_lock); ++DEFINE_RAW_SPINLOCK(dma_spin_lock); + EXPORT_SYMBOL(dma_spin_lock); + + static dma_t dma_chan[MAX_DMA_CHANNELS]; +diff -Nur custom-source-rt.orig/arch/arm/kernel/entry-armv.S custom-source-rt/arch/arm/kernel/entry-armv.S +--- custom-source-rt.orig/arch/arm/kernel/entry-armv.S 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/entry-armv.S 2007-10-02 17:31:08.000000000 +0000 +@@ -204,7 +204,7 @@ + irq_handler + #ifdef CONFIG_PREEMPT + ldr r0, [tsk, #TI_FLAGS] @ get flags +- tst r0, #_TIF_NEED_RESCHED ++ tst r0, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED + blne svc_preempt + preempt_return: + ldr r0, [tsk, #TI_PREEMPT] @ read preempt value +@@ -235,7 +235,7 @@ + str r7, [tsk, #TI_PREEMPT] @ expects preempt_count == 0 + 1: bl preempt_schedule_irq @ irq en/disable is done inside + ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS +- tst r0, #_TIF_NEED_RESCHED ++ tst r0, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED + beq preempt_return @ go again + b 1b + #endif +diff -Nur custom-source-rt.orig/arch/arm/kernel/entry-common.S custom-source-rt/arch/arm/kernel/entry-common.S +--- custom-source-rt.orig/arch/arm/kernel/entry-common.S 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/entry-common.S 2007-10-02 17:31:08.000000000 +0000 +@@ -3,6 +3,8 @@ + * + * Copyright (C) 2000 Russell King + * ++ * FUNCTION_TRACE/mcount support (C) 2005 Timesys john.cooper@timesys.com ++ * + * 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. +@@ -44,7 +46,7 @@ + fast_work_pending: + str r0, [sp, #S_R0+S_OFF]! @ returned r0 + work_pending: +- tst r1, #_TIF_NEED_RESCHED ++ tst r1, #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED + bne work_resched + tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING + beq no_work_pending +@@ -54,7 +56,8 @@ + b ret_slow_syscall @ Check work again + + work_resched: +- bl schedule ++ bl __schedule ++ + /* + * "slow" syscall return path. "why" tells us if this was a real syscall. + */ +@@ -394,6 +397,112 @@ + #include "calls.S" + #undef ABI + #undef OBSOLETE ++#endif ++ ++#ifdef CONFIG_FRAME_POINTER ++ ++#ifdef CONFIG_MCOUNT ++/* ++ * At the point where we are in mcount() we maintain the ++ * frame of the prologue code and keep the call to mcount() ++ * out of the stack frame list: ++ ++ saved pc <---\ caller of instrumented routine ++ saved lr | ++ ip/prev_sp | ++ fp -----^ | ++ : | ++ | ++ -> saved pc | instrumented routine ++ | saved lr | ++ | ip/prev_sp | ++ | fp ---------/ ++ | : ++ | ++ | mcount ++ | saved pc ++ | saved lr ++ | ip/prev sp ++ -- fp ++ r3 ++ r2 ++ r1 ++ sp-> r0 ++ : ++ */ ++ ++ .text ++ .align 0 ++ .type mcount %function ++ .global mcount ++ ++/* gcc -pg generated FUNCTION_PROLOGUE references mcount() ++ * and has already created the stack frame invocation for ++ * the routine we have been called to instrument. We create ++ * a complete frame nevertheless, as we want to use the same ++ * call to mcount() from c code. ++ */ ++mcount: ++ ++ ldr ip, =mcount_enabled @ leave early, if disabled ++ ldr ip, [ip] ++ cmp ip, #0 ++ moveq pc, lr ++ ++ mov ip, sp ++ stmdb sp!, {r0 - r3, fp, ip, lr, pc} @ create stack frame ++ ++ ldr r1, [fp, #-4] @ get lr (the return address ++ @ of the caller of the ++ @ instrumented function) ++ mov r0, lr @ get lr - (the return address ++ @ of the instrumented function) ++ ++ sub fp, ip, #4 @ point fp at this frame ++ ++ bl __trace ++1: ++ ldmdb fp, {r0 - r3, fp, sp, pc} @ pop entry frame and return ++ ++#endif ++ ++/* ARM replacement for unsupported gcc __builtin_return_address(n) ++ * where 0 < n. n == 0 is supported here as well. ++ * ++ * Walk up the stack frame until the desired frame is found or a NULL ++ * fp is encountered, return NULL in the latter case. ++ * ++ * Note: it is possible under code optimization for the stack invocation ++ * of an ancestor function (level N) to be removed before calling a ++ * descendant function (level N+1). No easy means is available to deduce ++ * this scenario with the result being [for example] caller_addr(0) when ++ * called from level N+1 returning level N-1 rather than the expected ++ * level N. This optimization issue appears isolated to the case of ++ * a call to a level N+1 routine made at the tail end of a level N ++ * routine -- the level N frame is deleted and a simple branch is made ++ * to the level N+1 routine. ++ */ ++ ++ .text ++ .align 0 ++ .type arm_return_addr %function ++ .global arm_return_addr ++ ++arm_return_addr: ++ mov ip, r0 ++ mov r0, fp ++3: ++ cmp r0, #0 ++ beq 1f @ frame list hit end, bail ++ cmp ip, #0 ++ beq 2f @ reached desired frame ++ ldr r0, [r0, #-12] @ else continue, get next fp ++ sub ip, ip, #1 ++ b 3b ++2: ++ ldr r0, [r0, #-4] @ get target return address ++1: ++ mov pc, lr + + #endif + +diff -Nur custom-source-rt.orig/arch/arm/kernel/fiq.c custom-source-rt/arch/arm/kernel/fiq.c +--- custom-source-rt.orig/arch/arm/kernel/fiq.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/fiq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -89,7 +89,7 @@ + * disable irqs for the duration. Note - these functions are almost + * entirely coded in assembly. + */ +-void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs) ++void notrace __attribute__((naked)) set_fiq_regs(struct pt_regs *regs) + { + register unsigned long tmp; + asm volatile ( +@@ -107,7 +107,7 @@ + : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); + } + +-void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs) ++void notrace __attribute__((naked)) get_fiq_regs(struct pt_regs *regs) + { + register unsigned long tmp; + asm volatile ( +diff -Nur custom-source-rt.orig/arch/arm/kernel/irq.c custom-source-rt/arch/arm/kernel/irq.c +--- custom-source-rt.orig/arch/arm/kernel/irq.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -100,7 +100,7 @@ + /* Handle bad interrupts */ + static struct irq_desc bad_irq_desc = { + .handle_irq = handle_bad_irq, +- .lock = SPIN_LOCK_UNLOCKED ++ .lock = RAW_SPIN_LOCK_UNLOCKED(bad_irq_desc.lock) + }; + + /* +@@ -108,11 +108,14 @@ + * come via this function. Instead, they should provide their + * own 'handler' + */ +-asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) ++asmlinkage void __exception notrace asm_do_IRQ(unsigned int irq, ++ struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); + struct irq_desc *desc = irq_desc + irq; + ++ trace_special(instruction_pointer(regs), irq, 0); ++ + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. +diff -Nur custom-source-rt.orig/arch/arm/kernel/process.c custom-source-rt/arch/arm/kernel/process.c +--- custom-source-rt.orig/arch/arm/kernel/process.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -130,7 +130,7 @@ + cpu_relax(); + else { + local_irq_disable(); +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + timer_dyn_reprogram(); + arch_idle(); + } +@@ -162,13 +162,17 @@ + idle = default_idle; + leds_event(led_idle_start); + tick_nohz_stop_sched_tick(); +- while (!need_resched()) ++ while (!need_resched() && !need_resched_delayed()) + idle(); + leds_event(led_idle_end); ++ local_irq_disable(); ++ trace_preempt_exit_idle(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ trace_preempt_enter_idle(); ++ local_irq_enable(); + } + } + +diff -Nur custom-source-rt.orig/arch/arm/kernel/semaphore.c custom-source-rt/arch/arm/kernel/semaphore.c +--- custom-source-rt.orig/arch/arm/kernel/semaphore.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -49,14 +49,16 @@ + * we cannot lose wakeup events. + */ + +-void __up(struct semaphore *sem) ++fastcall void __attribute_used__ __compat_up(struct compat_semaphore *sem) + { + wake_up(&sem->wait); + } + ++EXPORT_SYMBOL(__compat_up); ++ + static DEFINE_SPINLOCK(semaphore_lock); + +-void __sched __down(struct semaphore * sem) ++fastcall void __attribute_used__ __sched __compat_down(struct compat_semaphore * sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -89,7 +91,9 @@ + wake_up(&sem->wait); + } + +-int __sched __down_interruptible(struct semaphore * sem) ++EXPORT_SYMBOL(__compat_down); ++ ++fastcall int __attribute_used__ __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -140,6 +144,8 @@ + return retval; + } + ++EXPORT_SYMBOL(__compat_down_interruptible); ++ + /* + * Trylock failed - make sure we correct for + * having decremented the count. +@@ -148,7 +154,7 @@ + * single "cmpxchg" without failure cases, + * but then it wouldn't work on a 386. + */ +-int __down_trylock(struct semaphore * sem) ++fastcall int __attribute_used__ __sched __compat_down_trylock(struct compat_semaphore * sem) + { + int sleepers; + unsigned long flags; +@@ -168,6 +174,15 @@ + return 1; + } + ++EXPORT_SYMBOL(__compat_down_trylock); ++ ++fastcall int __sched compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} ++ ++EXPORT_SYMBOL(compat_sem_is_locked); ++ + /* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines +@@ -185,7 +200,7 @@ + __down_failed: \n\ + stmfd sp!, {r0 - r4, lr} \n\ + mov r0, ip \n\ +- bl __down \n\ ++ bl __compat_down \n\ + ldmfd sp!, {r0 - r4, pc} \n\ + \n\ + .align 5 \n\ +@@ -193,7 +208,7 @@ + __down_interruptible_failed: \n\ + stmfd sp!, {r0 - r4, lr} \n\ + mov r0, ip \n\ +- bl __down_interruptible \n\ ++ bl __compat_down_interruptible \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r4, pc} \n\ + \n\ +@@ -202,7 +217,7 @@ + __down_trylock_failed: \n\ + stmfd sp!, {r0 - r4, lr} \n\ + mov r0, ip \n\ +- bl __down_trylock \n\ ++ bl __compat_down_trylock \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r4, pc} \n\ + \n\ +@@ -211,7 +226,7 @@ + __up_wakeup: \n\ + stmfd sp!, {r0 - r4, lr} \n\ + mov r0, ip \n\ +- bl __up \n\ ++ bl __compat_up \n\ + ldmfd sp!, {r0 - r4, pc} \n\ + "); + +diff -Nur custom-source-rt.orig/arch/arm/kernel/signal.c custom-source-rt/arch/arm/kernel/signal.c +--- custom-source-rt.orig/arch/arm/kernel/signal.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -623,6 +623,14 @@ + siginfo_t info; + int signr; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +diff -Nur custom-source-rt.orig/arch/arm/kernel/smp.c custom-source-rt/arch/arm/kernel/smp.c +--- custom-source-rt.orig/arch/arm/kernel/smp.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -521,7 +521,7 @@ + cpu_clear(cpu, data->unfinished); + } + +-static DEFINE_SPINLOCK(stop_lock); ++static DEFINE_RAW_SPINLOCK(stop_lock); + + /* + * ipi_cpu_stop - handle IPI from smp_send_stop() +diff -Nur custom-source-rt.orig/arch/arm/kernel/time.c custom-source-rt/arch/arm/kernel/time.c +--- custom-source-rt.orig/arch/arm/kernel/time.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -236,6 +236,13 @@ + #define do_leds() + #endif + ++void arch_tick_leds(void) ++{ ++#ifdef CONFIG_LEDS_TIMER ++ do_leds(); ++#endif ++} ++ + #ifndef CONFIG_GENERIC_TIME + void do_gettimeofday(struct timeval *tv) + { +diff -Nur custom-source-rt.orig/arch/arm/kernel/traps.c custom-source-rt/arch/arm/kernel/traps.c +--- custom-source-rt.orig/arch/arm/kernel/traps.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -182,6 +182,7 @@ + void dump_stack(void) + { + __backtrace(); ++ print_traces(current); + } + + EXPORT_SYMBOL(dump_stack); +@@ -233,7 +234,7 @@ + } + } + +-DEFINE_SPINLOCK(die_lock); ++DEFINE_RAW_SPINLOCK(die_lock); + + /* + * This function is protected against re-entrancy. +@@ -275,7 +276,7 @@ + } + + static LIST_HEAD(undef_hook); +-static DEFINE_SPINLOCK(undef_lock); ++static DEFINE_RAW_SPINLOCK(undef_lock); + + void register_undef_hook(struct undef_hook *hook) + { +diff -Nur custom-source-rt.orig/arch/arm/lib/Makefile custom-source-rt/arch/arm/lib/Makefile +--- custom-source-rt.orig/arch/arm/lib/Makefile 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/lib/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -41,6 +41,7 @@ + lib-$(CONFIG_ARCH_CLPS7500) += io-acorn.o + lib-$(CONFIG_ARCH_L7200) += io-acorn.o + lib-$(CONFIG_ARCH_SHARK) += io-shark.o ++lib-$(CONFIG_STACKTRACE) += stacktrace.o + + $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S + $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S +diff -Nur custom-source-rt.orig/arch/arm/lib/stacktrace.c custom-source-rt/arch/arm/lib/stacktrace.c +--- custom-source-rt.orig/arch/arm/lib/stacktrace.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/arch/arm/lib/stacktrace.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,7 @@ ++#include ++#include ++ ++void save_stack_trace(struct stack_trace *trace) ++{ ++} ++ +diff -Nur custom-source-rt.orig/arch/arm/mach-davinci/time.c custom-source-rt/arch/arm/mach-davinci/time.c +--- custom-source-rt.orig/arch/arm/mach-davinci/time.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-davinci/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -285,6 +285,8 @@ + case CLOCK_EVT_MODE_SHUTDOWN: + t->opts = TIMER_OPTS_DISABLED; + break; ++ case CLOCK_EVT_MODE_RESUME: ++ break; + } + } + +diff -Nur custom-source-rt.orig/arch/arm/mach-ep93xx/core.c custom-source-rt/arch/arm/mach-ep93xx/core.c +--- custom-source-rt.orig/arch/arm/mach-ep93xx/core.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-ep93xx/core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,6 +32,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -50,7 +52,6 @@ + + #include + +- + /************************************************************************* + * Static I/O mappings that are needed for all EP93xx platforms + *************************************************************************/ +@@ -93,59 +94,125 @@ + * to use this timer for something else. We also use timer 4 for keeping + * track of lost jiffies. + */ +-static unsigned int last_jiffy_time; +- +-#define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) ++static struct clock_event_device clockevent_ep93xx; + + static int ep93xx_timer_interrupt(int irq, void *dev_id) + { +- write_seqlock(&xtime_lock); ++ __raw_writel(EP93XX_TC_CLEAR, EP93XX_TIMER1_CLEAR); + +- __raw_writel(1, EP93XX_TIMER1_CLEAR); +- while ((signed long) +- (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) +- >= TIMER4_TICKS_PER_JIFFY) { +- last_jiffy_time += TIMER4_TICKS_PER_JIFFY; +- timer_tick(); +- } +- +- write_sequnlock(&xtime_lock); ++ clockevent_ep93xx.event_handler(&clockevent_ep93xx); + + return IRQ_HANDLED; + } + ++static int ep93xx_set_next_event(unsigned long evt, ++ struct clock_event_device *unused) ++{ ++ u32 tmode = __raw_readl(EP93XX_TIMER1_CONTROL); ++ ++ /* stop timer */ ++ __raw_writel(tmode & ~EP93XX_TC123_ENABLE, EP93XX_TIMER1_CONTROL); ++ /* program timer */ ++ __raw_writel(evt, EP93XX_TIMER1_LOAD); ++ /* start timer */ ++ __raw_writel(tmode | EP93XX_TC123_ENABLE, EP93XX_TIMER1_CONTROL); ++ ++ return 0; ++} ++ ++static void ep93xx_set_mode(enum clock_event_mode mode, ++ struct clock_event_device *evt) ++{ ++ u32 tmode = EP93XX_TC123_SEL_508KHZ; ++ ++ /* Disable timer */ ++ __raw_writel(tmode, EP93XX_TIMER1_CONTROL); ++ ++ switch(mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ /* Set timer period */ ++ __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD); ++ tmode |= EP93XX_TC123_PERIODIC; ++ ++ case CLOCK_EVT_MODE_ONESHOT: ++ tmode |= EP93XX_TC123_ENABLE; ++ __raw_writel(tmode, EP93XX_TIMER1_CONTROL); ++ break; ++ ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ case CLOCK_EVT_MODE_UNUSED: ++ case CLOCK_EVT_MODE_RESUME: ++ return; ++ } ++} ++ ++static struct clock_event_device clockevent_ep93xx = { ++ .name = "ep93xx-timer1", ++ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, ++ .shift = 32, ++ .set_mode = ep93xx_set_mode, ++ .set_next_event = ep93xx_set_next_event, ++}; ++ ++ + static struct irqaction ep93xx_timer_irq = { + .name = "ep93xx timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = ep93xx_timer_interrupt, + }; + +-static void __init ep93xx_timer_init(void) ++static void __init ep93xx_clockevent_init(void) + { +- /* Enable periodic HZ timer. */ +- __raw_writel(0x48, EP93XX_TIMER1_CONTROL); +- __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD); +- __raw_writel(0xc8, EP93XX_TIMER1_CONTROL); ++ setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); + +- /* Enable lost jiffy timer. */ +- __raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH); ++ clockevent_ep93xx.mult = div_sc(508469, NSEC_PER_SEC, ++ clockevent_ep93xx.shift); ++ clockevent_ep93xx.max_delta_ns = ++ clockevent_delta2ns(0xfffffffe, &clockevent_ep93xx); ++ clockevent_ep93xx.min_delta_ns = ++ clockevent_delta2ns(0xf, &clockevent_ep93xx); ++ clockevent_ep93xx.cpumask = cpumask_of_cpu(0); ++ clockevents_register_device(&clockevent_ep93xx); ++} + +- setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); ++/* ++ * timer4 is a 40 Bit timer, separated in a 32bit and a 8 bit ++ * register, EP93XX_TIMER4_VALUE_LOW stores 32 bit word. The ++ * controlregister is in EP93XX_TIMER4_VALUE_HIGH ++ */ ++ ++cycle_t ep93xx_get_cycles(void) ++{ ++ return __raw_readl(EP93XX_TIMER4_VALUE_LOW); + } + +-static unsigned long ep93xx_gettimeoffset(void) ++static struct clocksource clocksource_ep93xx = { ++ .name = "ep93xx_timer4", ++ .rating = 200, ++ .read = ep93xx_get_cycles, ++ .mask = 0xFFFFFFFF, ++ .shift = 20, ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++static void __init ep93xx_clocksource_init(void) + { +- int offset; ++ /* Reset time-stamp counter */ ++ __raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH); + +- offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time; ++ clocksource_ep93xx.mult = ++ clocksource_hz2mult(983040, clocksource_ep93xx.shift); ++ clocksource_register(&clocksource_ep93xx); ++} + +- /* Calculate (1000000 / 983040) * offset. */ +- return offset + (53 * offset / 3072); ++static void __init ep93xx_timer_init(void) ++{ ++ ep93xx_clocksource_init(); ++ ep93xx_clockevent_init(); + } + + struct sys_timer ep93xx_timer = { +- .init = ep93xx_timer_init, +- .offset = ep93xx_gettimeoffset, ++ .init = ep93xx_timer_init, + }; + + +@@ -497,7 +564,6 @@ + .resource = ep93xx_ohci_resources, + }; + +- + void __init ep93xx_init_devices(void) + { + unsigned int v; +diff -Nur custom-source-rt.orig/arch/arm/mach-footbridge/netwinder-hw.c custom-source-rt/arch/arm/mach-footbridge/netwinder-hw.c +--- custom-source-rt.orig/arch/arm/mach-footbridge/netwinder-hw.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-footbridge/netwinder-hw.c 2007-10-02 17:31:08.000000000 +0000 +@@ -67,7 +67,7 @@ + /* + * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE + */ +-DEFINE_SPINLOCK(gpio_lock); ++DEFINE_RAW_SPINLOCK(gpio_lock); + + static unsigned int current_gpio_op; + static unsigned int current_gpio_io; +diff -Nur custom-source-rt.orig/arch/arm/mach-footbridge/netwinder-leds.c custom-source-rt/arch/arm/mach-footbridge/netwinder-leds.c +--- custom-source-rt.orig/arch/arm/mach-footbridge/netwinder-leds.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-footbridge/netwinder-leds.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,7 +32,7 @@ + static char hw_led_state; + + static DEFINE_SPINLOCK(leds_lock); +-extern spinlock_t gpio_lock; ++extern raw_spinlock_t gpio_lock; + + static void netwinder_leds_event(led_event_t evt) + { +diff -Nur custom-source-rt.orig/arch/arm/mach-imx/time.c custom-source-rt/arch/arm/mach-imx/time.c +--- custom-source-rt.orig/arch/arm/mach-imx/time.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-imx/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -3,6 +3,7 @@ + * + * Copyright (C) 2000-2001 Deep Blue Solutions + * Copyright (C) 2002 Shane Nay (shane@minirl.com) ++ * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) + * + * 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 +@@ -15,6 +16,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -25,7 +27,8 @@ + /* Use timer 1 as system timer */ + #define TIMER_BASE IMX_TIM1_BASE + +-static unsigned long evt_diff; ++static struct clock_event_device clockevent_imx; ++static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; + + /* + * IRQ handler for the timer +@@ -33,25 +36,20 @@ + static irqreturn_t + imx_timer_interrupt(int irq, void *dev_id) + { ++ struct clock_event_device *evt = &clockevent_imx; + uint32_t tstat; ++ irqreturn_t ret = IRQ_NONE; + + /* clear the interrupt */ + tstat = IMX_TSTAT(TIMER_BASE); + IMX_TSTAT(TIMER_BASE) = 0; + + if (tstat & TSTAT_COMP) { +- do { +- +- write_seqlock(&xtime_lock); +- timer_tick(); +- write_sequnlock(&xtime_lock); +- IMX_TCMP(TIMER_BASE) += evt_diff; +- +- } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE) +- - IMX_TCN(TIMER_BASE)) < 0)); ++ evt->event_handler(evt); ++ ret = IRQ_HANDLED; + } + +- return IRQ_HANDLED; ++ return ret; + } + + static struct irqaction imx_timer_irq = { +@@ -70,10 +68,8 @@ + */ + IMX_TCTL(TIMER_BASE) = 0; + IMX_TPRER(TIMER_BASE) = 0; +- IMX_TCMP(TIMER_BASE) = LATCH - 1; + +- IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN; +- evt_diff = LATCH; ++ IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN; + } + + cycle_t imx_get_cycles(void) +@@ -99,11 +95,108 @@ + return 0; + } + ++static int imx_set_next_event(unsigned long evt, ++ struct clock_event_device *unused) ++{ ++ unsigned long tcmp; ++ ++ tcmp = IMX_TCN(TIMER_BASE) + evt; ++ IMX_TCMP(TIMER_BASE) = tcmp; ++ ++ return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0; ++} ++ ++#ifdef DEBUG ++static const char *clock_event_mode_label[]={ ++ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", ++ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", ++ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", ++ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED" ++}; ++#endif /*DEBUG*/ ++ ++static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) ++{ ++ unsigned long flags; ++ ++ /* ++ * The timer interrupt generation is disabled at least ++ * for enough time to call imx_set_next_event() ++ */ ++ local_irq_save(flags); ++ /* Disable interrupt in GPT module */ ++ IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN; ++ if (mode != clockevent_mode) { ++ /* Set event time into far-far future */ ++ IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3; ++ /* Clear pending interrupt */ ++ IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP; ++ } ++ ++#ifdef DEBUG ++ printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n", ++ clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]); ++#endif /*DEBUG*/ ++ ++ /* Remember timer mode */ ++ clockevent_mode = mode; ++ local_irq_restore(flags); ++ ++ switch (mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n"); ++ break; ++ case CLOCK_EVT_MODE_ONESHOT: ++ /* ++ * Do not put overhead of interrupt enable/disable into ++ * imx_set_next_event(), the core has about 4 minutes ++ * to call imx_set_next_event() or shutdown clock after ++ * mode switching ++ */ ++ local_irq_save(flags); ++ IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN; ++ local_irq_restore(flags); ++ break; ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ case CLOCK_EVT_MODE_UNUSED: ++ /* Left event sources disabled, no more interrupts appears */ ++ break; ++ } ++} ++ ++static struct clock_event_device clockevent_imx = { ++ .name = "imx_timer1", ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++ .shift = 32, ++ .set_mode = imx_set_mode, ++ .set_next_event = imx_set_next_event, ++ .rating = 200, ++}; ++ ++static int __init imx_clockevent_init(void) ++{ ++ clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, ++ clockevent_imx.shift); ++ clockevent_imx.max_delta_ns = ++ clockevent_delta2ns(0xfffffffe, &clockevent_imx); ++ clockevent_imx.min_delta_ns = ++ clockevent_delta2ns(0xf, &clockevent_imx); ++ ++ clockevent_imx.cpumask = cpumask_of_cpu(0); ++ ++ clockevents_register_device(&clockevent_imx); ++ ++ return 0; ++} ++ ++ + static void __init imx_timer_init(void) + { + imx_timer_hardware_init(); + imx_clocksource_init(); + ++ imx_clockevent_init(); ++ + /* + * Make irqs happen for the system timer + */ +diff -Nur custom-source-rt.orig/arch/arm/mach-integrator/core.c custom-source-rt/arch/arm/mach-integrator/core.c +--- custom-source-rt.orig/arch/arm/mach-integrator/core.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-integrator/core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -164,7 +164,7 @@ + + #define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET + +-static DEFINE_SPINLOCK(cm_lock); ++static DEFINE_RAW_SPINLOCK(cm_lock); + + /** + * cm_control - update the CM_CTRL register. +diff -Nur custom-source-rt.orig/arch/arm/mach-integrator/pci_v3.c custom-source-rt/arch/arm/mach-integrator/pci_v3.c +--- custom-source-rt.orig/arch/arm/mach-integrator/pci_v3.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-integrator/pci_v3.c 2007-10-02 17:31:08.000000000 +0000 +@@ -162,7 +162,7 @@ + * 7:2 register number + * + */ +-static DEFINE_SPINLOCK(v3_lock); ++static DEFINE_RAW_SPINLOCK(v3_lock); + + #define PCI_BUS_NONMEM_START 0x00000000 + #define PCI_BUS_NONMEM_SIZE SZ_256M +diff -Nur custom-source-rt.orig/arch/arm/mach-ixp4xx/common-pci.c custom-source-rt/arch/arm/mach-ixp4xx/common-pci.c +--- custom-source-rt.orig/arch/arm/mach-ixp4xx/common-pci.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-ixp4xx/common-pci.c 2007-10-02 17:31:08.000000000 +0000 +@@ -53,7 +53,7 @@ + * these transactions are atomic or we will end up + * with corrupt data on the bus or in a driver. + */ +-static DEFINE_SPINLOCK(ixp4xx_pci_lock); ++static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock); + + /* + * Read from PCI config space +diff -Nur custom-source-rt.orig/arch/arm/mach-ixp4xx/common.c custom-source-rt/arch/arm/mach-ixp4xx/common.c +--- custom-source-rt.orig/arch/arm/mach-ixp4xx/common.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-ixp4xx/common.c 2007-10-02 17:31:08.000000000 +0000 +@@ -459,6 +459,8 @@ + default: + osrt = opts = 0; + break; ++ case CLOCK_EVT_MODE_RESUME: ++ break; + } + + *IXP4XX_OSRT1 = osrt | opts; +diff -Nur custom-source-rt.orig/arch/arm/mach-omap1/time.c custom-source-rt/arch/arm/mach-omap1/time.c +--- custom-source-rt.orig/arch/arm/mach-omap1/time.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-omap1/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -156,6 +156,7 @@ + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: ++ case CLOCK_EVT_MODE_RESUME: + break; + } + } +diff -Nur custom-source-rt.orig/arch/arm/mach-sa1100/badge4.c custom-source-rt/arch/arm/mach-sa1100/badge4.c +--- custom-source-rt.orig/arch/arm/mach-sa1100/badge4.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-sa1100/badge4.c 2007-10-02 17:31:08.000000000 +0000 +@@ -240,15 +240,22 @@ + /* detect on->off and off->on transitions */ + if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { + /* was off, now on */ +- printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); + GPSR = BADGE4_GPIO_PCMEN5V; + } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { + /* was on, now off */ +- printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); + GPCR = BADGE4_GPIO_PCMEN5V; + } + + local_irq_restore(flags); ++ ++ /* detect on->off and off->on transitions */ ++ if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { ++ /* was off, now on */ ++ printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); ++ } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { ++ /* was on, now off */ ++ printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); ++ } + } + EXPORT_SYMBOL(badge4_set_5V); + +diff -Nur custom-source-rt.orig/arch/arm/mach-shark/leds.c custom-source-rt/arch/arm/mach-shark/leds.c +--- custom-source-rt.orig/arch/arm/mach-shark/leds.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mach-shark/leds.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,7 +32,7 @@ + static short hw_led_state; + static short saved_state; + +-static DEFINE_SPINLOCK(leds_lock); ++static DEFINE_RAW_SPINLOCK(leds_lock); + + short sequoia_read(int addr) { + outw(addr,0x24); +diff -Nur custom-source-rt.orig/arch/arm/mm/consistent.c custom-source-rt/arch/arm/mm/consistent.c +--- custom-source-rt.orig/arch/arm/mm/consistent.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/consistent.c 2007-10-02 17:31:08.000000000 +0000 +@@ -40,7 +40,7 @@ + * These are the page tables (2MB each) covering uncached, DMA consistent allocations + */ + static pte_t *consistent_pte[NUM_CONSISTENT_PTES]; +-static DEFINE_SPINLOCK(consistent_lock); ++static DEFINE_RAW_SPINLOCK(consistent_lock); + + /* + * VM region handling support. +diff -Nur custom-source-rt.orig/arch/arm/mm/copypage-v4mc.c custom-source-rt/arch/arm/mm/copypage-v4mc.c +--- custom-source-rt.orig/arch/arm/mm/copypage-v4mc.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/copypage-v4mc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -30,7 +30,7 @@ + #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ + L_PTE_CACHEABLE) + +-static DEFINE_SPINLOCK(minicache_lock); ++static DEFINE_RAW_SPINLOCK(minicache_lock); + + /* + * ARMv4 mini-dcache optimised copy_user_page +@@ -44,7 +44,7 @@ + * instruction. If your processor does not supply this, you have to write your + * own copy_user_page that does the right thing. + */ +-static void __attribute__((naked)) ++static void notrace __attribute__((naked)) + mc_copy_user_page(void *from, void *to) + { + asm volatile( +@@ -88,7 +88,7 @@ + /* + * ARMv4 optimised clear_user_page + */ +-void __attribute__((naked)) ++void notrace __attribute__((naked)) + v4_mc_clear_user_page(void *kaddr, unsigned long vaddr) + { + asm volatile( +diff -Nur custom-source-rt.orig/arch/arm/mm/copypage-v6.c custom-source-rt/arch/arm/mm/copypage-v6.c +--- custom-source-rt.orig/arch/arm/mm/copypage-v6.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/copypage-v6.c 2007-10-02 17:31:08.000000000 +0000 +@@ -26,7 +26,7 @@ + #define from_address (0xffff8000) + #define to_address (0xffffc000) + +-static DEFINE_SPINLOCK(v6_lock); ++static DEFINE_RAW_SPINLOCK(v6_lock); + + /* + * Copy the user page. No aliasing to deal with so we can just +diff -Nur custom-source-rt.orig/arch/arm/mm/copypage-xscale.c custom-source-rt/arch/arm/mm/copypage-xscale.c +--- custom-source-rt.orig/arch/arm/mm/copypage-xscale.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/copypage-xscale.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,7 +32,7 @@ + #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ + L_PTE_CACHEABLE) + +-static DEFINE_SPINLOCK(minicache_lock); ++static DEFINE_RAW_SPINLOCK(minicache_lock); + + /* + * XScale mini-dcache optimised copy_user_page +@@ -42,7 +42,7 @@ + * Dcache aliasing issue. The writes will be forwarded to the write buffer, + * and merged as appropriate. + */ +-static void __attribute__((naked)) ++static void notrace __attribute__((naked)) + mc_copy_user_page(void *from, void *to) + { + /* +@@ -110,7 +110,7 @@ + /* + * XScale optimised clear_user_page + */ +-void __attribute__((naked)) ++void notrace __attribute__((naked)) + xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr) + { + asm volatile( +diff -Nur custom-source-rt.orig/arch/arm/mm/fault.c custom-source-rt/arch/arm/mm/fault.c +--- custom-source-rt.orig/arch/arm/mm/fault.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -215,7 +215,7 @@ + return fault; + } + +-static int ++static notrace int + do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { + struct task_struct *tsk; +@@ -229,7 +229,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (in_atomic() || !mm || current->pagefault_disabled) + goto no_context; + + /* +@@ -315,7 +315,7 @@ + * interrupt or a critical region, and should only copy the information + * from the master page table, nothing more. + */ +-static int ++static notrace int + do_translation_fault(unsigned long addr, unsigned int fsr, + struct pt_regs *regs) + { +@@ -358,7 +358,7 @@ + * Some section permission faults need to be handled gracefully. + * They can happen due to a __{get,put}_user during an oops. + */ +-static int ++static notrace int + do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { + do_bad_area(addr, fsr, regs); +@@ -368,7 +368,7 @@ + /* + * This abort handler always returns "fault". + */ +-static int ++static notrace int + do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { + return 1; +@@ -423,7 +423,7 @@ + { do_bad, SIGBUS, 0, "unknown 31" } + }; + +-void __init ++void __init notrace + hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), + int sig, const char *name) + { +@@ -437,7 +437,7 @@ + /* + * Dispatch a data abort to the relevant handler. + */ +-asmlinkage void __exception ++asmlinkage void __exception notrace + do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { + const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); +@@ -456,7 +456,7 @@ + arm_notify_die("", regs, &info, fsr, 0); + } + +-asmlinkage void __exception ++asmlinkage void __exception notrace + do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) + { + do_translation_fault(addr, 0, regs); +diff -Nur custom-source-rt.orig/arch/arm/mm/mmu.c custom-source-rt/arch/arm/mm/mmu.c +--- custom-source-rt.orig/arch/arm/mm/mmu.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/mm/mmu.c 2007-10-02 17:31:08.000000000 +0000 +@@ -25,7 +25,7 @@ + + #include "mm.h" + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + extern void _stext, _etext, __data_start, _end; + extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +diff -Nur custom-source-rt.orig/arch/arm/oprofile/op_model_xscale.c custom-source-rt/arch/arm/oprofile/op_model_xscale.c +--- custom-source-rt.orig/arch/arm/oprofile/op_model_xscale.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/oprofile/op_model_xscale.c 2007-10-02 17:31:08.000000000 +0000 +@@ -381,8 +381,9 @@ + { + int ret; + u32 pmnc = read_pmnc(); ++ int irq_flags = IRQF_DISABLED | IRQF_NODELAY; + +- ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, IRQF_DISABLED, ++ ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, irq_flags, + "XScale PMU", (void *)results); + + if (ret < 0) { +diff -Nur custom-source-rt.orig/arch/arm/plat-omap/timer32k.c custom-source-rt/arch/arm/plat-omap/timer32k.c +--- custom-source-rt.orig/arch/arm/plat-omap/timer32k.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/arm/plat-omap/timer32k.c 2007-10-02 17:31:08.000000000 +0000 +@@ -156,6 +156,8 @@ + case CLOCK_EVT_MODE_SHUTDOWN: + omap_32k_timer_stop(); + break; ++ case CLOCK_EVT_MODE_RESUME: ++ break; + } + } + +diff -Nur custom-source-rt.orig/arch/i386/Kconfig custom-source-rt/arch/i386/Kconfig +--- custom-source-rt.orig/arch/i386/Kconfig 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -18,6 +18,10 @@ + bool + default y + ++config GENERIC_CMOS_UPDATE ++ bool ++ default y ++ + config CLOCKSOURCE_WATCHDOG + bool + default y +@@ -31,6 +35,10 @@ + default y + depends on X86_LOCAL_APIC + ++config NONIRQ_WAKEUP ++ bool ++ default y ++ + config LOCKDEP_SUPPORT + bool + default y +@@ -764,6 +772,14 @@ + depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) + default y + ++# ++# function tracing might turn this off: ++# ++config REGPARM ++ bool ++ depends on !MCOUNT ++ default y ++ + config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS +@@ -1053,6 +1069,8 @@ + + source "arch/i386/kernel/cpu/cpufreq/Kconfig" + ++source "drivers/cpuidle/Kconfig" ++ + endmenu + + menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" +diff -Nur custom-source-rt.orig/arch/i386/Kconfig.cpu custom-source-rt/arch/i386/Kconfig.cpu +--- custom-source-rt.orig/arch/i386/Kconfig.cpu 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/Kconfig.cpu 2007-10-02 17:31:08.000000000 +0000 +@@ -247,12 +247,16 @@ + + config RWSEM_GENERIC_SPINLOCK + bool +- depends on !X86_XADD ++ depends on !X86_XADD || PREEMPT_RT ++ default y ++ ++config ASM_SEMAPHORES ++ bool + default y + + config RWSEM_XCHGADD_ALGORITHM + bool +- depends on X86_XADD ++ depends on X86_XADD && !RWSEM_GENERIC_SPINLOCK + default y + + config ARCH_HAS_ILOG2_U32 +diff -Nur custom-source-rt.orig/arch/i386/Kconfig.debug custom-source-rt/arch/i386/Kconfig.debug +--- custom-source-rt.orig/arch/i386/Kconfig.debug 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/Kconfig.debug 2007-10-02 17:31:08.000000000 +0000 +@@ -55,6 +55,7 @@ + config DEBUG_RODATA + bool "Write protect kernel read-only data structures" + depends on DEBUG_KERNEL ++ default y + help + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const +@@ -65,6 +66,7 @@ + config 4KSTACKS + bool "Use 4Kb for kernel stacks instead of 8Kb" + depends on DEBUG_KERNEL ++ default y + help + If you say Y here the kernel will use a 4Kb stacksize for the + kernel stack attached to each process/thread. This facilitates +diff -Nur custom-source-rt.orig/arch/i386/Makefile custom-source-rt/arch/i386/Makefile +--- custom-source-rt.orig/arch/i386/Makefile 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/arch/i386/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -31,7 +31,7 @@ + endif + CHECKFLAGS += -D__i386__ + +-CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return ++CFLAGS += -pipe -msoft-float -freg-struct-return + + # prevent gcc from keeping the stack 16 byte aligned + CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) +@@ -39,6 +39,8 @@ + # CPU-specific tuning. Anything which can be shared with UML should go here. + include $(srctree)/arch/i386/Makefile.cpu + ++cflags-$(CONFIG_REGPARM) += -mregparm=3 ++ + # temporary until string.h is fixed + cflags-y += -ffreestanding + +diff -Nur custom-source-rt.orig/arch/i386/boot/compressed/Makefile custom-source-rt/arch/i386/boot/compressed/Makefile +--- custom-source-rt.orig/arch/i386/boot/compressed/Makefile 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/boot/compressed/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -9,6 +9,7 @@ + EXTRA_AFLAGS := -traditional + + LDFLAGS_vmlinux := -T ++CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing + CFLAGS_misc.o += -fPIC + hostprogs-y := relocs + +diff -Nur custom-source-rt.orig/arch/i386/kernel/Makefile custom-source-rt/arch/i386/kernel/Makefile +--- custom-source-rt.orig/arch/i386/kernel/Makefile 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -21,6 +21,7 @@ + obj-$(CONFIG_X86_SMP) += smp.o smpboot.o tsc_sync.o + obj-$(CONFIG_SMP) += smpcommon.o + obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o ++obj-$(CONFIG_MCOUNT) += mcount-wrapper.o + obj-$(CONFIG_X86_MPPARSE) += mpparse.o + obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o + obj-$(CONFIG_X86_IO_APIC) += io_apic.o +diff -Nur custom-source-rt.orig/arch/i386/kernel/apic.c custom-source-rt/arch/i386/kernel/apic.c +--- custom-source-rt.orig/arch/i386/kernel/apic.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/apic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -264,6 +264,9 @@ + v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); + apic_write_around(APIC_LVTT, v); + break; ++ case CLOCK_EVT_MODE_RESUME: ++ /* Nothing to do here */ ++ break; + } + + local_irq_restore(flags); +@@ -316,7 +319,7 @@ + + #define LAPIC_CAL_LOOPS (HZ/10) + +-static __initdata volatile int lapic_cal_loops = -1; ++static __initdata int lapic_cal_loops = -1; + static __initdata long lapic_cal_t1, lapic_cal_t2; + static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2; + static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2; +@@ -483,7 +486,7 @@ + /* Let the interrupts run */ + local_irq_enable(); + +- while(lapic_cal_loops <= LAPIC_CAL_LOOPS) ++ while (lapic_cal_loops <= LAPIC_CAL_LOOPS) + cpu_relax(); + + local_irq_disable(); +@@ -519,6 +522,9 @@ + */ + if (nmi_watchdog != NMI_IO_APIC) + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; ++ else ++ printk(KERN_WARNING "APIC timer registered as dummy," ++ " due to nmi_watchdog=1!\n"); + } + + /* Setup the lapic or request the broadcast */ +@@ -571,10 +577,12 @@ + * interrupt as well. Thus we cannot inline the local irq ... ] + */ + +-void fastcall smp_apic_timer_interrupt(struct pt_regs *regs) ++void fastcall notrace smp_apic_timer_interrupt(struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); + ++ trace_special(regs->eip, 1, 0); ++ + /* + * NOTE! We'd better ACK the irq immediately, + * because timer handling can be slow. +@@ -1301,6 +1309,7 @@ + */ + printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n", + smp_processor_id(), v , v1); ++ dump_stack(); + irq_exit(); + } + +diff -Nur custom-source-rt.orig/arch/i386/kernel/apm.c custom-source-rt/arch/i386/kernel/apm.c +--- custom-source-rt.orig/arch/i386/kernel/apm.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/apm.c 2007-10-02 17:31:08.000000000 +0000 +@@ -782,7 +782,7 @@ + */ + smp_mb(); + } +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + idled = 1; + ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); + } +diff -Nur custom-source-rt.orig/arch/i386/kernel/cpu/mtrr/generic.c custom-source-rt/arch/i386/kernel/cpu/mtrr/generic.c +--- custom-source-rt.orig/arch/i386/kernel/cpu/mtrr/generic.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/cpu/mtrr/generic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -330,7 +330,7 @@ + + + static unsigned long cr4 = 0; +-static DEFINE_SPINLOCK(set_atomicity_lock); ++static DEFINE_RAW_SPINLOCK(set_atomicity_lock); + + /* + * Since we are disabling the cache don't allow any interrupts - they +diff -Nur custom-source-rt.orig/arch/i386/kernel/crash.c custom-source-rt/arch/i386/kernel/crash.c +--- custom-source-rt.orig/arch/i386/kernel/crash.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/crash.c 2007-10-02 17:31:08.000000000 +0000 +@@ -70,14 +70,6 @@ + return 1; + } + +-static void smp_send_nmi_allbutself(void) +-{ +- cpumask_t mask = cpu_online_map; +- cpu_clear(safe_smp_processor_id(), mask); +- if (!cpus_empty(mask)) +- send_IPI_mask(mask, NMI_VECTOR); +-} +- + static struct notifier_block crash_nmi_nb = { + .notifier_call = crash_nmi_callback, + }; +diff -Nur custom-source-rt.orig/arch/i386/kernel/efi.c custom-source-rt/arch/i386/kernel/efi.c +--- custom-source-rt.orig/arch/i386/kernel/efi.c 2007-08-21 04:00:16.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/efi.c 2007-10-02 17:31:08.000000000 +0000 +@@ -278,7 +278,7 @@ + struct range { + unsigned long start; + unsigned long end; +- } prev, curr; ++ } prev = { } /* shut up gcc */ , curr = { } /* shut up gcc */ ; + efi_memory_desc_t *md; + unsigned long start, end; + void *p; +diff -Nur custom-source-rt.orig/arch/i386/kernel/entry.S custom-source-rt/arch/i386/kernel/entry.S +--- custom-source-rt.orig/arch/i386/kernel/entry.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -264,14 +264,18 @@ + #ifdef CONFIG_PREEMPT + ENTRY(resume_kernel) + DISABLE_INTERRUPTS(CLBR_ANY) ++ cmpl $0, kernel_preemption ++ jz restore_nocheck + cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? + jnz restore_nocheck + need_resched: + movl TI_flags(%ebp), %ecx # need_resched set ? + testb $_TIF_NEED_RESCHED, %cl +- jz restore_all ++ jz restore_nocheck + testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ? +- jz restore_all ++ jz restore_nocheck ++ DISABLE_INTERRUPTS(CLBR_ANY) ++ + call preempt_schedule_irq + jmp need_resched + END(resume_kernel) +@@ -329,6 +333,11 @@ + pushl %eax + CFI_ADJUST_CFA_OFFSET 4 + SAVE_ALL ++#ifdef CONFIG_EVENT_TRACE ++ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax ++ call sys_call ++ popl %eax; popl %ebx; popl %ecx; popl %edx ++#endif + GET_THREAD_INFO(%ebp) + + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ +@@ -343,6 +352,11 @@ + movl TI_flags(%ebp), %ecx + testw $_TIF_ALLWORK_MASK, %cx + jne syscall_exit_work ++#ifdef CONFIG_EVENT_TRACE ++ pushl %eax ++ call sys_ret ++ popl %eax ++#endif + /* if something modifies registers it must also disable sysexit */ + movl PT_EIP(%esp), %edx + movl PT_OLDESP(%esp), %ecx +@@ -366,6 +380,11 @@ + pushl %eax # save orig_eax + CFI_ADJUST_CFA_OFFSET 4 + SAVE_ALL ++#ifdef CONFIG_EVENT_TRACE ++ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax ++ call sys_call ++ popl %eax; popl %ebx; popl %ecx; popl %edx ++#endif + GET_THREAD_INFO(%ebp) + # system call tracing in operation / emulation + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ +@@ -465,19 +484,19 @@ + ALIGN + RING0_PTREGS_FRAME # can't unwind into user space anyway + work_pending: +- testb $_TIF_NEED_RESCHED, %cl ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), %ecx + jz work_notifysig + work_resched: +- call schedule +- DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt ++ DISABLE_INTERRUPTS(CLBR_ANY) ++ call __schedule ++ # make sure we don't miss an interrupt + # setting need_resched or sigpending + # between sampling and the iret +- TRACE_IRQS_OFF + movl TI_flags(%ebp), %ecx + andl $_TIF_WORK_MASK, %ecx # is there any work to be done other + # than syscall tracing? + jz restore_all +- testb $_TIF_NEED_RESCHED, %cl ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED), %ecx + jnz work_resched + + work_notifysig: # deal with pending signals and +diff -Nur custom-source-rt.orig/arch/i386/kernel/head.S custom-source-rt/arch/i386/kernel/head.S +--- custom-source-rt.orig/arch/i386/kernel/head.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/head.S 2007-10-02 17:31:08.000000000 +0000 +@@ -486,6 +486,7 @@ + call printk + #endif + addl $(5*4),%esp ++ call dump_stack + popl %ds + popl %es + popl %edx +diff -Nur custom-source-rt.orig/arch/i386/kernel/hpet.c custom-source-rt/arch/i386/kernel/hpet.c +--- custom-source-rt.orig/arch/i386/kernel/hpet.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/hpet.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1,16 +1,18 @@ + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + ++#include + #include ++#include + #include + +-extern struct clock_event_device *global_clock_event; +- + #define HPET_MASK CLOCKSOURCE_MASK(32) + #define HPET_SHIFT 22 + +@@ -21,9 +23,9 @@ + * HPET address is set in acpi/boot.c, when an ACPI entry exists + */ + unsigned long hpet_address; +-static void __iomem * hpet_virt_address; ++static void __iomem *hpet_virt_address; + +-static inline unsigned long hpet_readl(unsigned long a) ++unsigned long hpet_readl(unsigned long a) + { + return readl(hpet_virt_address + a); + } +@@ -33,6 +35,36 @@ + writel(d, hpet_virt_address + a); + } + ++#ifdef CONFIG_X86_64 ++ ++#include ++ ++static inline void hpet_set_mapping(void) ++{ ++ set_fixmap_nocache(FIX_HPET_BASE, hpet_address); ++ __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); ++ hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); ++} ++ ++static inline void hpet_clear_mapping(void) ++{ ++ hpet_virt_address = NULL; ++} ++ ++#else ++ ++static inline void hpet_set_mapping(void) ++{ ++ hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); ++} ++ ++static inline void hpet_clear_mapping(void) ++{ ++ iounmap(hpet_virt_address); ++ hpet_virt_address = NULL; ++} ++#endif ++ + /* + * HPET command line enable / disable + */ +@@ -48,6 +80,13 @@ + } + __setup("hpet=", hpet_setup); + ++static int __init disable_hpet(char *str) ++{ ++ boot_hpet_disable = 1; ++ return 1; ++} ++__setup("nohpet", disable_hpet); ++ + static inline int is_hpet_capable(void) + { + return (!boot_hpet_disable && hpet_address); +@@ -82,7 +121,7 @@ + + memset(&hd, 0, sizeof (hd)); + hd.hd_phys_address = hpet_address; +- hd.hd_address = hpet_virt_address; ++ hd.hd_address = hpet; + hd.hd_nirqs = nrtimers; + hd.hd_flags = HPET_DATA_PLATFORM; + hpet_reserve_timer(&hd, 0); +@@ -110,9 +149,9 @@ + */ + static unsigned long hpet_period; + +-static void hpet_set_mode(enum clock_event_mode mode, ++static void hpet_legacy_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt); +-static int hpet_next_event(unsigned long delta, ++static int hpet_legacy_next_event(unsigned long delta, + struct clock_event_device *evt); + + /* +@@ -121,10 +160,11 @@ + static struct clock_event_device hpet_clockevent = { + .name = "hpet", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, +- .set_mode = hpet_set_mode, +- .set_next_event = hpet_next_event, ++ .set_mode = hpet_legacy_set_mode, ++ .set_next_event = hpet_legacy_next_event, + .shift = 32, + .irq = 0, ++ .rating = 50, + }; + + static void hpet_start_counter(void) +@@ -139,7 +179,18 @@ + hpet_writel(cfg, HPET_CFG); + } + +-static void hpet_enable_int(void) ++static void hpet_resume_device(void) ++{ ++ force_hpet_resume(); ++} ++ ++static void hpet_restart_counter(void) ++{ ++ hpet_resume_device(); ++ hpet_start_counter(); ++} ++ ++static void hpet_enable_legacy_int(void) + { + unsigned long cfg = hpet_readl(HPET_CFG); + +@@ -148,7 +199,39 @@ + hpet_legacy_int_enabled = 1; + } + +-static void hpet_set_mode(enum clock_event_mode mode, ++static void hpet_legacy_clockevent_register(void) ++{ ++ uint64_t hpet_freq; ++ ++ /* Start HPET legacy interrupts */ ++ hpet_enable_legacy_int(); ++ ++ /* ++ * The period is a femto seconds value. We need to calculate the ++ * scaled math multiplication factor for nanosecond to hpet tick ++ * conversion. ++ */ ++ hpet_freq = 1000000000000000ULL; ++ do_div(hpet_freq, hpet_period); ++ hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, ++ NSEC_PER_SEC, 32); ++ /* Calculate the min / max delta */ ++ hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, ++ &hpet_clockevent); ++ hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30, ++ &hpet_clockevent); ++ ++ /* ++ * Start hpet with the boot cpu mask and make it ++ * global after the IO_APIC has been initialized. ++ */ ++ hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); ++ clockevents_register_device(&hpet_clockevent); ++ global_clock_event = &hpet_clockevent; ++ printk(KERN_DEBUG "hpet clockevent registered\n"); ++} ++ ++static void hpet_legacy_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) + { + unsigned long cfg, cmp, now; +@@ -187,10 +270,14 @@ + cfg &= ~HPET_TN_ENABLE; + hpet_writel(cfg, HPET_T0_CFG); + break; ++ ++ case CLOCK_EVT_MODE_RESUME: ++ hpet_enable_legacy_int(); ++ break; + } + } + +-static int hpet_next_event(unsigned long delta, ++static int hpet_legacy_next_event(unsigned long delta, + struct clock_event_device *evt) + { + unsigned long cnt; +@@ -205,11 +292,18 @@ + /* + * Clock source related code + */ +-static cycle_t read_hpet(void) ++static cycle_t notrace read_hpet(void) + { + return (cycle_t)hpet_readl(HPET_COUNTER); + } + ++#ifdef CONFIG_X86_64 ++static cycle_t __vsyscall_fn vread_hpet(void) ++{ ++ return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); ++} ++#endif ++ + static struct clocksource clocksource_hpet = { + .name = "hpet", + .rating = 250, +@@ -217,60 +311,17 @@ + .mask = HPET_MASK, + .shift = HPET_SHIFT, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++ .resume = hpet_restart_counter, ++#ifdef CONFIG_X86_64 ++ .vread = vread_hpet, ++#endif + }; + +-/* +- * Try to setup the HPET timer +- */ +-int __init hpet_enable(void) ++static int hpet_clocksource_register(void) + { +- unsigned long id; +- uint64_t hpet_freq; + u64 tmp, start, now; + cycle_t t1; + +- if (!is_hpet_capable()) +- return 0; +- +- hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); +- +- /* +- * Read the period and check for a sane value: +- */ +- hpet_period = hpet_readl(HPET_PERIOD); +- if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) +- goto out_nohpet; +- +- /* +- * The period is a femto seconds value. We need to calculate the +- * scaled math multiplication factor for nanosecond to hpet tick +- * conversion. +- */ +- hpet_freq = 1000000000000000ULL; +- do_div(hpet_freq, hpet_period); +- hpet_clockevent.mult = div_sc((unsigned long) hpet_freq, +- NSEC_PER_SEC, 32); +- /* Calculate the min / max delta */ +- hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, +- &hpet_clockevent); +- hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30, +- &hpet_clockevent); +- +- /* +- * Read the HPET ID register to retrieve the IRQ routing +- * information and the number of channels +- */ +- id = hpet_readl(HPET_ID); +- +-#ifdef CONFIG_HPET_EMULATE_RTC +- /* +- * The legacy routing mode needs at least two channels, tick timer +- * and the rtc emulation channel. +- */ +- if (!(id & HPET_ID_NUMBER)) +- goto out_nohpet; +-#endif +- + /* Start the counter */ + hpet_start_counter(); + +@@ -292,7 +343,7 @@ + if (t1 == read_hpet()) { + printk(KERN_WARNING + "HPET counter not counting. HPET disabled\n"); +- goto out_nohpet; ++ return -ENODEV; + } + + /* Initialize and register HPET clocksource +@@ -313,28 +364,84 @@ + + clocksource_register(&clocksource_hpet); + ++ return 0; ++} ++ ++/* ++ * Try to setup the HPET timer ++ */ ++int __init hpet_enable(void) ++{ ++ unsigned long id; ++ ++ if (!is_hpet_capable()) ++ return 0; ++ ++ hpet_set_mapping(); ++ ++ /* ++ * Read the period and check for a sane value: ++ */ ++ hpet_period = hpet_readl(HPET_PERIOD); ++ if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) ++ goto out_nohpet; ++ ++ /* ++ * Read the HPET ID register to retrieve the IRQ routing ++ * information and the number of channels ++ */ ++ id = hpet_readl(HPET_ID); ++ ++#ifdef CONFIG_HPET_EMULATE_RTC ++ /* ++ * The legacy routing mode needs at least two channels, tick timer ++ * and the rtc emulation channel. ++ */ ++ if (!(id & HPET_ID_NUMBER)) ++ goto out_nohpet; ++#endif ++ ++ if (hpet_clocksource_register()) ++ goto out_nohpet; + + if (id & HPET_ID_LEGSUP) { +- hpet_enable_int(); +- hpet_reserve_platform_timers(id); +- /* +- * Start hpet with the boot cpu mask and make it +- * global after the IO_APIC has been initialized. +- */ +- hpet_clockevent.cpumask =cpumask_of_cpu(0); +- clockevents_register_device(&hpet_clockevent); +- global_clock_event = &hpet_clockevent; ++ hpet_legacy_clockevent_register(); + return 1; + } + return 0; + + out_nohpet: +- iounmap(hpet_virt_address); +- hpet_virt_address = NULL; ++ hpet_clear_mapping(); + boot_hpet_disable = 1; + return 0; + } + ++/* ++ * Needs to be late, as the reserve_timer code calls kalloc ! ++ * ++ * Not a problem on i386 as hpet_enable is called from late_time_init, ++ * but on x86_64 it is necessary ! ++ */ ++static __init int hpet_late_init(void) ++{ ++ if (boot_hpet_disable) ++ return -ENODEV; ++ ++ if (!hpet_address) { ++ if (!force_hpet_address) ++ return -ENODEV; ++ ++ hpet_address = force_hpet_address; ++ hpet_enable(); ++ if (!hpet_virt_address) ++ return -ENODEV; ++ } ++ ++ hpet_reserve_platform_timers(hpet_readl(HPET_ID)); ++ ++ return 0; ++} ++fs_initcall(hpet_late_init); + + #ifdef CONFIG_HPET_EMULATE_RTC + +@@ -546,68 +653,3 @@ + return IRQ_HANDLED; + } + #endif +- +- +-/* +- * Suspend/resume part +- */ +- +-#ifdef CONFIG_PM +- +-static int hpet_suspend(struct sys_device *sys_device, pm_message_t state) +-{ +- unsigned long cfg = hpet_readl(HPET_CFG); +- +- cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY); +- hpet_writel(cfg, HPET_CFG); +- +- return 0; +-} +- +-static int hpet_resume(struct sys_device *sys_device) +-{ +- unsigned int id; +- +- hpet_start_counter(); +- +- id = hpet_readl(HPET_ID); +- +- if (id & HPET_ID_LEGSUP) +- hpet_enable_int(); +- +- return 0; +-} +- +-static struct sysdev_class hpet_class = { +- set_kset_name("hpet"), +- .suspend = hpet_suspend, +- .resume = hpet_resume, +-}; +- +-static struct sys_device hpet_device = { +- .id = 0, +- .cls = &hpet_class, +-}; +- +- +-static __init int hpet_register_sysfs(void) +-{ +- int err; +- +- if (!is_hpet_capable()) +- return 0; +- +- err = sysdev_class_register(&hpet_class); +- +- if (!err) { +- err = sysdev_register(&hpet_device); +- if (err) +- sysdev_class_unregister(&hpet_class); +- } +- +- return err; +-} +- +-device_initcall(hpet_register_sysfs); +- +-#endif +diff -Nur custom-source-rt.orig/arch/i386/kernel/i386_ksyms.c custom-source-rt/arch/i386/kernel/i386_ksyms.c +--- custom-source-rt.orig/arch/i386/kernel/i386_ksyms.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/i386_ksyms.c 2007-10-02 17:31:08.000000000 +0000 +@@ -2,10 +2,12 @@ + #include + #include + +-EXPORT_SYMBOL(__down_failed); +-EXPORT_SYMBOL(__down_failed_interruptible); +-EXPORT_SYMBOL(__down_failed_trylock); +-EXPORT_SYMBOL(__up_wakeup); ++#ifdef CONFIG_ASM_SEMAPHORES ++EXPORT_SYMBOL(__compat_down_failed); ++EXPORT_SYMBOL(__compat_down_failed_interruptible); ++EXPORT_SYMBOL(__compat_down_failed_trylock); ++EXPORT_SYMBOL(__compat_up_wakeup); ++#endif + /* Networking helper routines. */ + EXPORT_SYMBOL(csum_partial_copy_generic); + +@@ -20,7 +22,7 @@ + + EXPORT_SYMBOL(strstr); + +-#ifdef CONFIG_SMP ++#if defined(CONFIG_SMP) && defined(CONFIG_ASM_SEMAPHORES) + extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); + extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); + EXPORT_SYMBOL(__write_lock_failed); +diff -Nur custom-source-rt.orig/arch/i386/kernel/i8253.c custom-source-rt/arch/i386/kernel/i8253.c +--- custom-source-rt.orig/arch/i386/kernel/i8253.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/i8253.c 2007-10-02 17:31:08.000000000 +0000 +@@ -3,20 +3,18 @@ + * + */ + #include +-#include ++#include ++#include + #include +-#include + #include +-#include ++#include + + #include + #include + #include + #include + +-#include "io_ports.h" +- +-DEFINE_SPINLOCK(i8253_lock); ++DEFINE_RAW_SPINLOCK(i8253_lock); + EXPORT_SYMBOL(i8253_lock); + + /* +@@ -41,26 +39,27 @@ + case CLOCK_EVT_MODE_PERIODIC: + /* binary, mode 2, LSB/MSB, ch 0 */ + outb_p(0x34, PIT_MODE); +- udelay(10); + outb_p(LATCH & 0xff , PIT_CH0); /* LSB */ +- udelay(10); + outb(LATCH >> 8 , PIT_CH0); /* MSB */ + break; + +- /* +- * Avoid unnecessary state transitions, as it confuses +- * Geode / Cyrix based boxen. +- */ + case CLOCK_EVT_MODE_SHUTDOWN: +- if (evt->mode == CLOCK_EVT_MODE_UNUSED) +- break; + case CLOCK_EVT_MODE_UNUSED: +- if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN) +- break; ++ if (evt->mode == CLOCK_EVT_MODE_PERIODIC || ++ evt->mode == CLOCK_EVT_MODE_ONESHOT) { ++ outb_p(0x30, PIT_MODE); ++ outb_p(0, PIT_CH0); ++ outb_p(0, PIT_CH0); ++ } ++ break; ++ + case CLOCK_EVT_MODE_ONESHOT: + /* One shot setup */ + outb_p(0x38, PIT_MODE); +- udelay(10); ++ break; ++ ++ case CLOCK_EVT_MODE_RESUME: ++ /* Nothing to do here */ + break; + } + spin_unlock_irqrestore(&i8253_lock, flags); +@@ -120,6 +119,7 @@ + global_clock_event = &pit_clockevent; + } + ++#ifndef CONFIG_X86_64 + /* + * Since the PIT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free +@@ -204,3 +204,5 @@ + return clocksource_register(&clocksource_pit); + } + arch_initcall(init_pit_clocksource); ++ ++#endif +diff -Nur custom-source-rt.orig/arch/i386/kernel/i8259.c custom-source-rt/arch/i386/kernel/i8259.c +--- custom-source-rt.orig/arch/i386/kernel/i8259.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/i8259.c 2007-10-02 17:31:08.000000000 +0000 +@@ -34,7 +34,7 @@ + */ + + static int i8259A_auto_eoi; +-DEFINE_SPINLOCK(i8259A_lock); ++DEFINE_RAW_SPINLOCK(i8259A_lock); + static void mask_and_ack_8259A(unsigned int); + + static struct irq_chip i8259A_chip = { +@@ -170,6 +170,8 @@ + */ + if (cached_irq_mask & irqmask) + goto spurious_8259A_irq; ++ if (irq & 8) ++ outb(0x60+(irq&7),PIC_SLAVE_CMD); /* 'Specific EOI' to slave */ + cached_irq_mask |= irqmask; + + handle_real_irq: +@@ -297,10 +299,10 @@ + outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ + outb_p(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ + outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ +- if (auto_eoi) /* master does Auto EOI */ +- outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); +- else /* master expects normal EOI */ ++ if (!auto_eoi) /* master expects normal EOI */ + outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); ++ else /* master does Auto EOI */ ++ outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); + + outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ + outb_p(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ +@@ -350,7 +352,7 @@ + * New motherboards sometimes make IRQ 13 be a PCI interrupt, + * so allow interrupt sharing. + */ +-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; ++static struct irqaction fpu_irq = { math_error_irq, IRQF_NODELAY, CPU_MASK_NONE, "fpu", NULL, NULL }; + + void __init init_ISA_irqs (void) + { +diff -Nur custom-source-rt.orig/arch/i386/kernel/io_apic.c custom-source-rt/arch/i386/kernel/io_apic.c +--- custom-source-rt.orig/arch/i386/kernel/io_apic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/io_apic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -56,8 +56,8 @@ + /* Where if anywhere is the i8259 connect in external int mode */ + static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + +-static DEFINE_SPINLOCK(ioapic_lock); +-static DEFINE_SPINLOCK(vector_lock); ++static DEFINE_RAW_SPINLOCK(ioapic_lock); ++static DEFINE_RAW_SPINLOCK(vector_lock); + + int timer_over_8254 __initdata = 1; + +@@ -261,14 +261,14 @@ + __modify_IO_APIC_irq(irq, 0, 0x00010000); + } + +-/* mask = 1, trigger = 0 */ +-static void __mask_and_edge_IO_APIC_irq (unsigned int irq) ++/* trigger = 0 (edge mode) */ ++static void __pcix_mask_IO_APIC_irq (unsigned int irq) + { +- __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); ++ __modify_IO_APIC_irq(irq, 0, 0x00008000); + } + +-/* mask = 0, trigger = 1 */ +-static void __unmask_and_level_IO_APIC_irq (unsigned int irq) ++/* mask = 0, trigger = 1 (level mode) */ ++static void __pcix_unmask_IO_APIC_irq (unsigned int irq) + { + __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); + } +@@ -291,6 +291,24 @@ + spin_unlock_irqrestore(&ioapic_lock, flags); + } + ++static void pcix_mask_IO_APIC_irq (unsigned int irq) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __pcix_mask_IO_APIC_irq(irq); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++} ++ ++static void pcix_unmask_IO_APIC_irq (unsigned int irq) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __pcix_unmask_IO_APIC_irq(irq); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++} ++ + static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) + { + struct IO_APIC_route_entry entry; +@@ -1266,21 +1284,27 @@ + + return vector; + } ++ + static struct irq_chip ioapic_chip; ++static struct irq_chip pcix_ioapic_chip; + + #define IOAPIC_AUTO -1 + #define IOAPIC_EDGE 0 + #define IOAPIC_LEVEL 1 + +-static void ioapic_register_intr(int irq, int vector, unsigned long trigger) ++static void ioapic_register_intr(int irq, int vector, unsigned long trigger, ++ int pcix) + { ++ struct irq_chip *chip = pcix ? &pcix_ioapic_chip : &ioapic_chip; ++ + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) +- set_irq_chip_and_handler_name(irq, &ioapic_chip, +- handle_fasteoi_irq, "fasteoi"); ++ set_irq_chip_and_handler_name(irq, chip, handle_fasteoi_irq, ++ pcix ? "pcix-fasteoi" : "fasteoi"); + else +- set_irq_chip_and_handler_name(irq, &ioapic_chip, +- handle_edge_irq, "edge"); ++ set_irq_chip_and_handler_name(irq, chip, handle_edge_irq, ++ pcix ? "pcix-edge" : "edge"); ++ + set_intr_gate(vector, interrupt[irq]); + } + +@@ -1344,7 +1368,8 @@ + if (IO_APIC_IRQ(irq)) { + vector = assign_irq_vector(irq); + entry.vector = vector; +- ioapic_register_intr(irq, vector, IOAPIC_AUTO); ++ ioapic_register_intr(irq, vector, IOAPIC_AUTO, ++ apic > 0); + + if (!apic && (irq < 16)) + disable_8259A_irq(irq); +@@ -1515,7 +1540,7 @@ + return; + } + +-#if 0 ++#if 1 + + static void print_APIC_bitfield (int base) + { +@@ -1919,7 +1944,7 @@ + * might have cached one ExtINT interrupt. Finally, at + * least one tick may be lost due to delays. + */ +- if (jiffies - t1 > 4) ++ if (jiffies - t1 > 4 && jiffies - t1 < 16) + return 1; + + return 0; +@@ -2008,8 +2033,10 @@ + if (!(v & (1 << (i & 0x1f)))) { + atomic_inc(&irq_mis_count); + spin_lock(&ioapic_lock); +- __mask_and_edge_IO_APIC_irq(irq); +- __unmask_and_level_IO_APIC_irq(irq); ++ /* mask = 1, trigger = 0 */ ++ __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); ++ /* mask = 0, trigger = 1 */ ++ __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); + spin_unlock(&ioapic_lock); + } + } +@@ -2034,6 +2061,18 @@ + .retrigger = ioapic_retrigger_irq, + }; + ++static struct irq_chip pcix_ioapic_chip __read_mostly = { ++ .name = "IO-APIC", ++ .startup = startup_ioapic_irq, ++ .mask = pcix_mask_IO_APIC_irq, ++ .unmask = pcix_unmask_IO_APIC_irq, ++ .ack = ack_ioapic_irq, ++ .eoi = ack_ioapic_irq, ++#ifdef CONFIG_SMP ++ .set_affinity = set_ioapic_affinity_irq, ++#endif ++ .retrigger = ioapic_retrigger_irq, ++}; + + static inline void init_IO_APIC_traps(void) + { +@@ -2834,7 +2873,7 @@ + mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, + edge_level, active_high_low); + +- ioapic_register_intr(irq, entry.vector, edge_level); ++ ioapic_register_intr(irq, entry.vector, edge_level, ioapic > 0); + + if (!ioapic && (irq < 16)) + disable_8259A_irq(irq); +diff -Nur custom-source-rt.orig/arch/i386/kernel/irq.c custom-source-rt/arch/i386/kernel/irq.c +--- custom-source-rt.orig/arch/i386/kernel/irq.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -68,7 +68,7 @@ + * SMP cross-CPU interrupts have their own specific + * handlers). + */ +-fastcall unsigned int do_IRQ(struct pt_regs *regs) ++fastcall notrace unsigned int do_IRQ(struct pt_regs *regs) + { + struct pt_regs *old_regs; + /* high bit used in ret_from_ code */ +@@ -79,6 +79,10 @@ + u32 *isp; + #endif + ++#ifdef CONFIG_X86_LOCAL_APIC ++ irq_show_regs_callback(smp_processor_id(), regs); ++#endif ++ + if (unlikely((unsigned)irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); +@@ -87,6 +91,11 @@ + + old_regs = set_irq_regs(regs); + irq_enter(); ++#ifdef CONFIG_EVENT_TRACE ++ if (irq == trace_user_trigger_irq) ++ user_trace_start(); ++#endif ++ trace_special(regs->eip, irq, 0); + #ifdef CONFIG_DEBUG_STACKOVERFLOW + /* Debugging check for stack overflow: is there less than 1KB free? */ + { +@@ -95,7 +104,7 @@ + __asm__ __volatile__("andl %%esp,%0" : + "=r" (esp) : "0" (THREAD_SIZE - 1)); + if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { +- printk("do_IRQ: stack overflow: %ld\n", ++ printk("BUG: do_IRQ: stack overflow: %ld\n", + esp - sizeof(struct thread_info)); + dump_stack(); + } +diff -Nur custom-source-rt.orig/arch/i386/kernel/kprobes.c custom-source-rt/arch/i386/kernel/kprobes.c +--- custom-source-rt.orig/arch/i386/kernel/kprobes.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/kprobes.c 2007-10-02 17:31:08.000000000 +0000 +@@ -329,7 +329,7 @@ + /* Boost up -- we can execute copied instructions directly */ + reset_current_kprobe(); + regs->eip = (unsigned long)p->ainsn.insn; +- preempt_enable_no_resched(); ++ preempt_enable(); + return 1; + } + #endif +@@ -338,7 +338,7 @@ + return 1; + + no_kprobe: +- preempt_enable_no_resched(); ++ preempt_enable(); + return ret; + } + +@@ -569,7 +569,7 @@ + } + reset_current_kprobe(); + out: +- preempt_enable_no_resched(); ++ preempt_enable(); + + /* + * if somebody else is singlestepping across a probe point, eflags +@@ -603,7 +603,7 @@ + restore_previous_kprobe(kcb); + else + reset_current_kprobe(); +- preempt_enable_no_resched(); ++ preempt_enable(); + break; + case KPROBE_HIT_ACTIVE: + case KPROBE_HIT_SSDONE: +@@ -665,12 +665,11 @@ + break; + case DIE_GPF: + case DIE_PAGE_FAULT: ++ // TODO: do this better on PREEMPT_RT + /* kprobe_running() needs smp_processor_id() */ +- preempt_disable(); +- if (kprobe_running() && ++ if (per_cpu(current_kprobe, raw_smp_processor_id()) && + kprobe_fault_handler(args->regs, args->trapnr)) + ret = NOTIFY_STOP; +- preempt_enable(); + break; + default: + break; +@@ -737,7 +736,7 @@ + *regs = kcb->jprobe_saved_regs; + memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, + MIN_STACK_SIZE(stack_addr)); +- preempt_enable_no_resched(); ++ preempt_enable(); + return 1; + } + return 0; +diff -Nur custom-source-rt.orig/arch/i386/kernel/mcount-wrapper.S custom-source-rt/arch/i386/kernel/mcount-wrapper.S +--- custom-source-rt.orig/arch/i386/kernel/mcount-wrapper.S 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/mcount-wrapper.S 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,27 @@ ++/* ++ * linux/arch/i386/mcount-wrapper.S ++ * ++ * Copyright (C) 2004 Ingo Molnar ++ */ ++ ++.globl mcount ++mcount: ++ ++ cmpl $0, mcount_enabled ++ jz out ++ ++ push %ebp ++ mov %esp, %ebp ++ pushl %eax ++ pushl %ecx ++ pushl %edx ++ ++ call __mcount ++ ++ popl %edx ++ popl %ecx ++ popl %eax ++ popl %ebp ++out: ++ ret ++ +diff -Nur custom-source-rt.orig/arch/i386/kernel/microcode.c custom-source-rt/arch/i386/kernel/microcode.c +--- custom-source-rt.orig/arch/i386/kernel/microcode.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/microcode.c 2007-10-02 17:31:08.000000000 +0000 +@@ -116,7 +116,7 @@ + #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) + + /* serialize access to the physical write to MSR 0x79 */ +-static DEFINE_SPINLOCK(microcode_update_lock); ++static DEFINE_RAW_SPINLOCK(microcode_update_lock); + + /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ + static DEFINE_MUTEX(microcode_mutex); +diff -Nur custom-source-rt.orig/arch/i386/kernel/nmi.c custom-source-rt/arch/i386/kernel/nmi.c +--- custom-source-rt.orig/arch/i386/kernel/nmi.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/nmi.c 2007-10-02 17:31:08.000000000 +0000 +@@ -28,6 +28,8 @@ + #include + #include + ++#include ++ + #include "mach_traps.h" + + int unknown_nmi_panic; +@@ -44,7 +46,7 @@ + atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ + + unsigned int nmi_watchdog = NMI_DEFAULT; +-static unsigned int nmi_hz = HZ; ++static unsigned int nmi_hz = 1000; + + static DEFINE_PER_CPU(short, wd_enabled); + +@@ -60,7 +62,12 @@ + */ + static __init void nmi_cpu_busy(void *data) + { ++ /* ++ * avoid a warning, on PREEMPT_RT this wont run in hardirq context: ++ */ ++#ifndef CONFIG_PREEMPT_RT + local_irq_enable_in_hardirq(); ++#endif + /* Intentionally don't use cpu_relax here. This is + to make sure that the performance counter really ticks, + even if there is a simulator or similar that catches the +@@ -95,7 +102,7 @@ + for_each_possible_cpu(cpu) + prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; + local_irq_enable(); +- mdelay((20*1000)/nmi_hz); // wait 20 ticks ++ mdelay((100*1000)/nmi_hz); /* wait 100 ticks */ + + for_each_possible_cpu(cpu) { + #ifdef CONFIG_SMP +@@ -317,9 +324,48 @@ + + extern void die_nmi(struct pt_regs *, const char *msg); + +-__kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) ++int nmi_show_regs[NR_CPUS]; ++ ++void nmi_show_all_regs(void) ++{ ++ int i; ++ ++ if (system_state == SYSTEM_BOOTING) ++ return; ++ ++ printk(KERN_WARNING "nmi_show_all_regs(): start on CPU#%d.\n", ++ raw_smp_processor_id()); ++ dump_stack(); ++ ++ for_each_online_cpu(i) ++ nmi_show_regs[i] = 1; ++ ++ smp_send_nmi_allbutself(); ++ ++ for_each_online_cpu(i) { ++ while (nmi_show_regs[i] == 1) ++ barrier(); ++ } ++} ++ ++static DEFINE_RAW_SPINLOCK(nmi_print_lock); ++ ++notrace void irq_show_regs_callback(int cpu, struct pt_regs *regs) + { ++ if (!nmi_show_regs[cpu]) ++ return; ++ ++ nmi_show_regs[cpu] = 0; ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", ++ per_cpu(irq_stat, cpu).apic_timer_irqs); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++} + ++notrace __kprobes int nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) ++{ + /* + * Since current_thread_info()-> is always on the stack, and we + * always switch the stack NMI-atomically, it's safe to use +@@ -330,6 +376,8 @@ + int cpu = smp_processor_id(); + int rc=0; + ++ __profile_tick(CPU_PROFILING, regs); ++ + /* check for other users first */ + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { +@@ -342,7 +390,7 @@ + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); +- dump_stack(); ++ show_regs(regs); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } +@@ -353,6 +401,9 @@ + */ + sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_irqs(0); + ++ irq_show_regs_callback(cpu, regs); ++ ++ /* if the apic timer isn't firing, this cpu isn't doing much */ + /* if the none of the timers isn't firing, this cpu isn't doing much */ + if (!touched && last_irq_sums[cpu] == sum) { + /* +@@ -360,11 +411,29 @@ + * wait a few IRQs (5 seconds) before doing the oops ... + */ + alert_counter[cpu]++; +- if (alert_counter[cpu] == 5*nmi_hz) +- /* +- * die_nmi will return ONLY if NOTIFY_STOP happens.. +- */ +- die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP"); ++ if (alert_counter[cpu] && !(alert_counter[cpu] % (5*nmi_hz))) { ++ int i; ++ ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI watchdog detected lockup on " ++ "CPU#%d (%d/%d)\n", cpu, alert_counter[cpu], ++ 5*nmi_hz); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); ++ ++ for_each_online_cpu(i) { ++ if (i == cpu) ++ continue; ++ nmi_show_regs[i] = 1; ++ while (nmi_show_regs[i] == 1) ++ cpu_relax(); ++ } ++ printk(KERN_WARNING "NMI watchdog running again ...\n"); ++ for_each_online_cpu(i) ++ alert_counter[i] = 0; ++ ++ } ++ + } else { + last_irq_sums[cpu] = sum; + alert_counter[cpu] = 0; +@@ -462,5 +531,15 @@ + } + } + ++void smp_send_nmi_allbutself(void) ++{ ++#ifdef CONFIG_SMP ++ cpumask_t mask = cpu_online_map; ++ cpu_clear(safe_smp_processor_id(), mask); ++ if (!cpus_empty(mask)) ++ send_IPI_mask(mask, NMI_VECTOR); ++#endif ++} ++ + EXPORT_SYMBOL(nmi_active); + EXPORT_SYMBOL(nmi_watchdog); +diff -Nur custom-source-rt.orig/arch/i386/kernel/paravirt.c custom-source-rt/arch/i386/kernel/paravirt.c +--- custom-source-rt.orig/arch/i386/kernel/paravirt.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/paravirt.c 2007-10-02 17:31:08.000000000 +0000 +@@ -228,6 +228,16 @@ + } + core_initcall(print_banner); + ++#ifdef CONFIG_HIGHPTE ++/* ++ * kmap_atomic() might be an inline or a macro: ++ */ ++static void *kmap_atomic_func(struct page *page, enum km_type idx) ++{ ++ return kmap_atomic(page, idx); ++} ++#endif ++ + struct paravirt_ops paravirt_ops = { + .name = "bare hardware", + .paravirt_enabled = 0, +@@ -316,7 +326,7 @@ + .pte_update_defer = paravirt_nop, + + #ifdef CONFIG_HIGHPTE +- .kmap_atomic_pte = kmap_atomic, ++ .kmap_atomic_pte = kmap_atomic_func, + #endif + + #ifdef CONFIG_X86_PAE +diff -Nur custom-source-rt.orig/arch/i386/kernel/process.c custom-source-rt/arch/i386/kernel/process.c +--- custom-source-rt.orig/arch/i386/kernel/process.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -115,7 +115,7 @@ + smp_mb(); + + local_irq_disable(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) + safe_halt(); /* enables interrupts racelessly */ + else + local_irq_enable(); +@@ -136,7 +136,9 @@ + */ + static void poll_idle (void) + { +- cpu_relax(); ++ do { ++ cpu_relax(); ++ } while (!need_resched() && !need_resched_delayed()); + } + + #ifdef CONFIG_HOTPLUG_CPU +@@ -179,14 +181,14 @@ + + /* endless idle loop with no priority at all */ + while (1) { +- tick_nohz_stop_sched_tick(); +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + void (*idle)(void); + + if (__get_cpu_var(cpu_idle_state)) + __get_cpu_var(cpu_idle_state) = 0; + +- check_pgt_cache(); ++ tick_nohz_stop_sched_tick(); ++ + rmb(); + idle = pm_idle; + +@@ -199,10 +201,14 @@ + __get_cpu_var(irq_stat).idle_timestamp = jiffies; + idle(); + } ++ local_irq_disable(); ++ trace_preempt_exit_idle(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ trace_preempt_enter_idle(); ++ local_irq_enable(); + } + } + +@@ -248,10 +254,10 @@ + */ + void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) + { +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) + __mwait(eax, ecx); + } + } +@@ -368,15 +374,23 @@ + if (unlikely(test_thread_flag(TIF_IO_BITMAP))) { + struct task_struct *tsk = current; + struct thread_struct *t = &tsk->thread; +- int cpu = get_cpu(); +- struct tss_struct *tss = &per_cpu(init_tss, cpu); ++ void *io_bitmap_ptr = t->io_bitmap_ptr; ++ int cpu; ++ struct tss_struct *tss; + +- kfree(t->io_bitmap_ptr); ++ /* ++ * On PREEMPT_RT we must not call kfree() with ++ * preemption disabled, so we first zap the pointer: ++ */ + t->io_bitmap_ptr = NULL; ++ kfree(io_bitmap_ptr); ++ + clear_thread_flag(TIF_IO_BITMAP); + /* + * Careful, clear this in the TSS too: + */ ++ cpu = get_cpu(); ++ tss = &per_cpu(init_tss, cpu); + memset(tss->io_bitmap, 0xff, tss->io_bitmap_max); + t->io_bitmap_max = 0; + tss->io_bitmap_owner = NULL; +diff -Nur custom-source-rt.orig/arch/i386/kernel/quirks.c custom-source-rt/arch/i386/kernel/quirks.c +--- custom-source-rt.orig/arch/i386/kernel/quirks.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/quirks.c 2007-10-02 17:31:08.000000000 +0000 +@@ -4,6 +4,8 @@ + #include + #include + ++#include ++ + #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) + + static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) +@@ -47,3 +49,280 @@ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); + #endif ++ ++#if defined(CONFIG_HPET_TIMER) ++unsigned long force_hpet_address; ++ ++static enum { ++ NONE_FORCE_HPET_RESUME, ++ OLD_ICH_FORCE_HPET_RESUME, ++ ICH_FORCE_HPET_RESUME, ++ VT8237_FORCE_HPET_RESUME ++} force_hpet_resume_type; ++ ++static void __iomem *rcba_base; ++ ++static void ich_force_hpet_resume(void) ++{ ++ u32 val; ++ ++ if (!force_hpet_address) ++ return; ++ ++ if (rcba_base == NULL) ++ BUG(); ++ ++ /* read the Function Disable register, dword mode only */ ++ val = readl(rcba_base + 0x3404); ++ if (!(val & 0x80)) { ++ /* HPET disabled in HPTC. Trying to enable */ ++ writel(val | 0x80, rcba_base + 0x3404); ++ } ++ ++ val = readl(rcba_base + 0x3404); ++ if (!(val & 0x80)) ++ BUG(); ++ else ++ printk(KERN_DEBUG "Force enabled HPET at resume\n"); ++ ++ return; ++} ++ ++static void ich_force_enable_hpet(struct pci_dev *dev) ++{ ++ u32 val; ++ u32 uninitialized_var(rcba); ++ int err = 0; ++ ++ if (hpet_address || force_hpet_address) ++ return; ++ ++ pci_read_config_dword(dev, 0xF0, &rcba); ++ rcba &= 0xFFFFC000; ++ if (rcba == 0) { ++ printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n"); ++ return; ++ } ++ ++ /* use bits 31:14, 16 kB aligned */ ++ rcba_base = ioremap_nocache(rcba, 0x4000); ++ if (rcba_base == NULL) { ++ printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n"); ++ return; ++ } ++ ++ /* read the Function Disable register, dword mode only */ ++ val = readl(rcba_base + 0x3404); ++ ++ if (val & 0x80) { ++ /* HPET is enabled in HPTC. Just not reported by BIOS */ ++ val = val & 0x3; ++ force_hpet_address = 0xFED00000 | (val << 12); ++ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", ++ force_hpet_address); ++ iounmap(rcba_base); ++ return; ++ } ++ ++ /* HPET disabled in HPTC. Trying to enable */ ++ writel(val | 0x80, rcba_base + 0x3404); ++ ++ val = readl(rcba_base + 0x3404); ++ if (!(val & 0x80)) { ++ err = 1; ++ } else { ++ val = val & 0x3; ++ force_hpet_address = 0xFED00000 | (val << 12); ++ } ++ ++ if (err) { ++ force_hpet_address = 0; ++ iounmap(rcba_base); ++ printk(KERN_DEBUG "Failed to force enable HPET\n"); ++ } else { ++ force_hpet_resume_type = ICH_FORCE_HPET_RESUME; ++ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", ++ force_hpet_address); ++ } ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, ++ ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, ++ ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, ++ ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, ++ ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, ++ ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, ++ ich_force_enable_hpet); ++ ++ ++static struct pci_dev *cached_dev; ++ ++static void old_ich_force_hpet_resume(void) ++{ ++ u32 val; ++ u32 uninitialized_var(gen_cntl); ++ ++ if (!force_hpet_address || !cached_dev) ++ return; ++ ++ pci_read_config_dword(cached_dev, 0xD0, &gen_cntl); ++ gen_cntl &= (~(0x7 << 15)); ++ gen_cntl |= (0x4 << 15); ++ ++ pci_write_config_dword(cached_dev, 0xD0, gen_cntl); ++ pci_read_config_dword(cached_dev, 0xD0, &gen_cntl); ++ val = gen_cntl >> 15; ++ val &= 0x7; ++ if (val == 0x4) ++ printk(KERN_DEBUG "Force enabled HPET at resume\n"); ++ else ++ BUG(); ++} ++ ++static void old_ich_force_enable_hpet(struct pci_dev *dev) ++{ ++ u32 val; ++ u32 uninitialized_var(gen_cntl); ++ ++ if (hpet_address || force_hpet_address) ++ return; ++ ++ pci_read_config_dword(dev, 0xD0, &gen_cntl); ++ /* ++ * Bit 17 is HPET enable bit. ++ * Bit 16:15 control the HPET base address. ++ */ ++ val = gen_cntl >> 15; ++ val &= 0x7; ++ if (val & 0x4) { ++ val &= 0x3; ++ force_hpet_address = 0xFED00000 | (val << 12); ++ printk(KERN_DEBUG "HPET at base address 0x%lx\n", ++ force_hpet_address); ++ return; ++ } ++ ++ /* ++ * HPET is disabled. Trying enabling at FED00000 and check ++ * whether it sticks ++ */ ++ gen_cntl &= (~(0x7 << 15)); ++ gen_cntl |= (0x4 << 15); ++ pci_write_config_dword(dev, 0xD0, gen_cntl); ++ ++ pci_read_config_dword(dev, 0xD0, &gen_cntl); ++ ++ val = gen_cntl >> 15; ++ val &= 0x7; ++ if (val & 0x4) { ++ /* HPET is enabled in HPTC. Just not reported by BIOS */ ++ val &= 0x3; ++ force_hpet_address = 0xFED00000 | (val << 12); ++ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", ++ force_hpet_address); ++ cached_dev = dev; ++ force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME; ++ return; ++ } ++ ++ printk(KERN_DEBUG "Failed to force enable HPET\n"); ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, ++ old_ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, ++ old_ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, ++ old_ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, ++ old_ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, ++ old_ich_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, ++ old_ich_force_enable_hpet); ++ ++ ++static void vt8237_force_hpet_resume(void) ++{ ++ u32 val; ++ ++ if (!force_hpet_address || !cached_dev) ++ return; ++ ++ val = 0xfed00000 | 0x80; ++ pci_write_config_dword(cached_dev, 0x68, val); ++ ++ pci_read_config_dword(cached_dev, 0x68, &val); ++ if (val & 0x80) ++ printk(KERN_DEBUG "Force enabled HPET at resume\n"); ++ else ++ BUG(); ++} ++ ++static void vt8237_force_enable_hpet(struct pci_dev *dev) ++{ ++ u32 val; ++ ++ if (hpet_address || force_hpet_address) ++ return; ++ ++ pci_read_config_dword(dev, 0x68, &val); ++ /* ++ * Bit 7 is HPET enable bit. ++ * Bit 31:10 is HPET base address (contrary to what datasheet claims) ++ */ ++ if (val & 0x80) { ++ force_hpet_address = (val & ~0x3ff); ++ printk(KERN_DEBUG "HPET at base address 0x%lx\n", ++ force_hpet_address); ++ return; ++ } ++ ++ /* ++ * HPET is disabled. Trying enabling at FED00000 and check ++ * whether it sticks ++ */ ++ val = 0xfed00000 | 0x80; ++ pci_write_config_dword(dev, 0x68, val); ++ ++ pci_read_config_dword(dev, 0x68, &val); ++ if (val & 0x80) { ++ force_hpet_address = (val & ~0x3ff); ++ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", ++ force_hpet_address); ++ cached_dev = dev; ++ force_hpet_resume_type = VT8237_FORCE_HPET_RESUME; ++ return; ++ } ++ ++ printk(KERN_DEBUG "Failed to force enable HPET\n"); ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, ++ vt8237_force_enable_hpet); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, ++ vt8237_force_enable_hpet); ++ ++void force_hpet_resume(void) ++{ ++ switch (force_hpet_resume_type) { ++ case ICH_FORCE_HPET_RESUME: ++ return ich_force_hpet_resume(); ++ ++ case OLD_ICH_FORCE_HPET_RESUME: ++ return old_ich_force_hpet_resume(); ++ ++ case VT8237_FORCE_HPET_RESUME: ++ return vt8237_force_hpet_resume(); ++ ++ default: ++ break; ++ } ++} ++ ++#endif +diff -Nur custom-source-rt.orig/arch/i386/kernel/signal.c custom-source-rt/arch/i386/kernel/signal.c +--- custom-source-rt.orig/arch/i386/kernel/signal.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -533,6 +533,13 @@ + } + } + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * If TF is set due to a debugger (PT_DTRACE), clear the TF flag so + * that register information in the sigcontext is correct. +@@ -573,6 +580,13 @@ + struct k_sigaction ka; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +diff -Nur custom-source-rt.orig/arch/i386/kernel/smp.c custom-source-rt/arch/i386/kernel/smp.c +--- custom-source-rt.orig/arch/i386/kernel/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -246,7 +246,7 @@ + static cpumask_t flush_cpumask; + static struct mm_struct * flush_mm; + static unsigned long flush_va; +-static DEFINE_SPINLOCK(tlbstate_lock); ++static DEFINE_RAW_SPINLOCK(tlbstate_lock); + + /* + * We cannot call mmdrop() because we are in interrupt context, +@@ -474,10 +474,20 @@ + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ send_IPI_allbutself(RESCHEDULE_VECTOR); ++} ++ ++/* + * Structure and data for smp_call_function(). This is designed to minimise + * static memory requirements. It also looks cleaner. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + struct call_data_struct { + void (*func) (void *info); +@@ -632,13 +642,14 @@ + } + + /* +- * Reschedule call back. Nothing to do, +- * all the work is done automatically when +- * we return from the interrupt. ++ * Reschedule call back. Trigger a reschedule pass so that ++ * RT-overload balancing can pass tasks around. + */ +-fastcall void smp_reschedule_interrupt(struct pt_regs *regs) ++fastcall notrace void smp_reschedule_interrupt(struct pt_regs *regs) + { ++ trace_special(regs->eip, 0, 0); + ack_APIC_irq(); ++ set_tsk_need_resched(current); + } + + fastcall void smp_call_function_interrupt(struct pt_regs *regs) +diff -Nur custom-source-rt.orig/arch/i386/kernel/smpboot.c custom-source-rt/arch/i386/kernel/smpboot.c +--- custom-source-rt.orig/arch/i386/kernel/smpboot.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/smpboot.c 2007-10-02 17:31:08.000000000 +0000 +@@ -941,17 +941,6 @@ + } + #endif + +-static void smp_tune_scheduling(void) +-{ +- if (cpu_khz) { +- /* cache size in kB */ +- long cachesize = boot_cpu_data.x86_cache_size; +- +- if (cachesize > 0) +- max_cache_size = cachesize * 1024; +- } +-} +- + /* + * Cycle through the processors sending APIC IPIs to boot each. + */ +@@ -980,7 +969,6 @@ + x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; + + current_thread_info()->cpu = 0; +- smp_tune_scheduling(); + + set_cpu_sibling_map(0); + +diff -Nur custom-source-rt.orig/arch/i386/kernel/time.c custom-source-rt/arch/i386/kernel/time.c +--- custom-source-rt.orig/arch/i386/kernel/time.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -124,7 +124,7 @@ + + int timer_ack; + +-unsigned long profile_pc(struct pt_regs *regs) ++unsigned long notrace profile_pc(struct pt_regs *regs) + { + unsigned long pc = instruction_pointer(regs); + +@@ -207,55 +207,9 @@ + return retval; + } + +-static void sync_cmos_clock(unsigned long dummy); +- +-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); +-int no_sync_cmos_clock; +- +-static void sync_cmos_clock(unsigned long dummy) +-{ +- struct timeval now, next; +- int fail = 1; +- +- /* +- * If we have an externally synchronized Linux clock, then update +- * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be +- * called as close as possible to 500 ms before the new second starts. +- * This code is run on a timer. If the clock is set, that timer +- * may not expire at the correct time. Thus, we adjust... +- */ +- if (!ntp_synced()) +- /* +- * Not synced, exit, do not restart a timer (if one is +- * running, let it run out). +- */ +- return; +- +- do_gettimeofday(&now); +- if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 && +- now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) +- fail = set_rtc_mmss(now.tv_sec); +- +- next.tv_usec = USEC_AFTER - now.tv_usec; +- if (next.tv_usec <= 0) +- next.tv_usec += USEC_PER_SEC; +- +- if (!fail) +- next.tv_sec = 659; +- else +- next.tv_sec = 0; +- +- if (next.tv_usec >= USEC_PER_SEC) { +- next.tv_sec++; +- next.tv_usec -= USEC_PER_SEC; +- } +- mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next)); +-} +- +-void notify_arch_cmos_timer(void) ++int update_persistent_clock(struct timespec now) + { +- if (!no_sync_cmos_clock) +- mod_timer(&sync_cmos_timer, jiffies + 1); ++ return set_rtc_mmss(now.tv_sec); + } + + extern void (*late_time_init)(void); +diff -Nur custom-source-rt.orig/arch/i386/kernel/traps.c custom-source-rt/arch/i386/kernel/traps.c +--- custom-source-rt.orig/arch/i386/kernel/traps.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -222,6 +222,7 @@ + { + dump_trace(task, regs, stack, &print_trace_ops, log_lvl); + printk("%s =======================\n", log_lvl); ++ print_traces(task); + } + + void show_trace(struct task_struct *task, struct pt_regs *regs, +@@ -251,8 +252,15 @@ + printk("\n%s ", log_lvl); + printk("%08lx ", *stack++); + } ++ ++ pause_on_oops_head(); ++ + printk("\n%sCall Trace:\n", log_lvl); + show_trace_log_lvl(task, regs, esp, log_lvl); ++ ++ pause_on_oops_tail(); ++ ++ debug_show_held_locks(task); + } + + void show_stack(struct task_struct *task, unsigned long *esp) +@@ -273,6 +281,12 @@ + + EXPORT_SYMBOL(dump_stack); + ++#if defined(CONFIG_DEBUG_STACKOVERFLOW) && defined(CONFIG_EVENT_TRACE) ++extern unsigned long worst_stack_left; ++#else ++# define worst_stack_left -1L ++#endif ++ + void show_registers(struct pt_regs *regs) + { + int i; +@@ -301,8 +315,12 @@ + regs->eax, regs->ebx, regs->ecx, regs->edx); + printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + regs->esi, regs->edi, regs->ebp, esp); +- printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", +- regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss); ++ ++ printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x " ++ " preempt:%08x\n", ++ regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ++ ss, preempt_count()); ++ + printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", + TASK_COMM_LEN, current->comm, current->pid, + current_thread_info(), current, task_thread_info(current)); +@@ -362,11 +380,11 @@ + void die(const char * str, struct pt_regs * regs, long err) + { + static struct { +- spinlock_t lock; ++ raw_spinlock_t lock; + u32 lock_owner; + int lock_owner_depth; + } die = { +- .lock = __SPIN_LOCK_UNLOCKED(die.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(die.lock), + .lock_owner = -1, + .lock_owner_depth = 0 + }; +@@ -472,6 +490,11 @@ + if (!user_mode(regs)) + goto kernel_trap; + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + trap_signal: { + /* + * We want error_code and trap_no set for userspace faults and +@@ -711,10 +734,11 @@ + crash_kexec(regs); + } + ++ nmi_exit(); + do_exit(SIGSEGV); + } + +-static __kprobes void default_do_nmi(struct pt_regs * regs) ++static notrace __kprobes void default_do_nmi(struct pt_regs * regs) + { + unsigned char reason = 0; + +@@ -752,11 +776,12 @@ + reassert_nmi(); + } + +-fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) ++fastcall notrace __kprobes void do_nmi(struct pt_regs * regs, long error_code) + { + int cpu; + + nmi_enter(); ++ nmi_trace((unsigned long)do_nmi, regs->eip, regs->eflags); + + cpu = smp_processor_id(); + +diff -Nur custom-source-rt.orig/arch/i386/kernel/tsc.c custom-source-rt/arch/i386/kernel/tsc.c +--- custom-source-rt.orig/arch/i386/kernel/tsc.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/tsc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -4,6 +4,7 @@ + * See comments there for proper credits. + */ + ++#include + #include + #include + #include +@@ -106,8 +107,13 @@ + + /* + * Fall back to jiffies if there's no TSC available: ++ * ( But note that we still use it if the TSC is marked ++ * unstable. We do this because unlike Time Of Day, ++ * the scheduler clock tolerates small errors and it's ++ * very important for it to be as fast as the platform ++ * can achive it. ) + */ +- if (unlikely(!tsc_enabled)) ++ if (unlikely(!tsc_enabled && !tsc_unstable)) + /* No locking but a rare wrong value is not a big deal: */ + return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); + +@@ -255,7 +261,7 @@ + + static unsigned long current_tsc_khz = 0; + +-static cycle_t read_tsc(void) ++static notrace cycle_t read_tsc(void) + { + cycle_t ret; + +@@ -277,6 +283,7 @@ + + void mark_tsc_unstable(char *reason) + { ++ sched_clock_unstable_event(); + if (!tsc_unstable) { + tsc_unstable = 1; + tsc_enabled = 0; +diff -Nur custom-source-rt.orig/arch/i386/kernel/vm86.c custom-source-rt/arch/i386/kernel/vm86.c +--- custom-source-rt.orig/arch/i386/kernel/vm86.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/vm86.c 2007-10-02 17:31:08.000000000 +0000 +@@ -137,6 +137,7 @@ + local_irq_enable(); + + if (!current->thread.vm86_info) { ++ local_irq_disable(); + printk("no vm86_info: BAD\n"); + do_exit(SIGSEGV); + } +diff -Nur custom-source-rt.orig/arch/i386/kernel/vmiclock.c custom-source-rt/arch/i386/kernel/vmiclock.c +--- custom-source-rt.orig/arch/i386/kernel/vmiclock.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/kernel/vmiclock.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + #include "io_ports.h" +@@ -142,6 +143,7 @@ + + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: ++ case CLOCK_EVT_MODE_RESUME: + break; + case CLOCK_EVT_MODE_PERIODIC: + cycles_per_hz = vmi_timer_ops.get_cycle_frequency(); +diff -Nur custom-source-rt.orig/arch/i386/lib/delay.c custom-source-rt/arch/i386/lib/delay.c +--- custom-source-rt.orig/arch/i386/lib/delay.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/lib/delay.c 2007-10-02 17:31:08.000000000 +0000 +@@ -23,7 +23,7 @@ + #endif + + /* simple loop based delay: */ +-static void delay_loop(unsigned long loops) ++static notrace void delay_loop(unsigned long loops) + { + int d0; + +@@ -38,7 +38,7 @@ + } + + /* TSC based delay: */ +-static void delay_tsc(unsigned long loops) ++static notrace void delay_tsc(unsigned long loops) + { + unsigned long bclock, now; + +@@ -69,7 +69,7 @@ + return -1; + } + +-void __delay(unsigned long loops) ++void notrace __delay(unsigned long loops) + { + delay_fn(loops); + } +diff -Nur custom-source-rt.orig/arch/i386/lib/semaphore.S custom-source-rt/arch/i386/lib/semaphore.S +--- custom-source-rt.orig/arch/i386/lib/semaphore.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/lib/semaphore.S 2007-10-02 17:31:08.000000000 +0000 +@@ -30,7 +30,7 @@ + * value or just clobbered.. + */ + .section .sched.text +-ENTRY(__down_failed) ++ENTRY(__compat_down_failed) + CFI_STARTPROC + FRAME + pushl %edx +@@ -39,7 +39,7 @@ + pushl %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 +- call __down ++ call __compat_down + popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ecx +@@ -49,9 +49,9 @@ + ENDFRAME + ret + CFI_ENDPROC +- END(__down_failed) ++ END(__compat_down_failed) + +-ENTRY(__down_failed_interruptible) ++ENTRY(__compat_down_failed_interruptible) + CFI_STARTPROC + FRAME + pushl %edx +@@ -60,7 +60,7 @@ + pushl %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 +- call __down_interruptible ++ call __compat_down_interruptible + popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ecx +@@ -70,9 +70,9 @@ + ENDFRAME + ret + CFI_ENDPROC +- END(__down_failed_interruptible) ++ END(__compat_down_failed_interruptible) + +-ENTRY(__down_failed_trylock) ++ENTRY(__compat_down_failed_trylock) + CFI_STARTPROC + FRAME + pushl %edx +@@ -81,7 +81,7 @@ + pushl %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 +- call __down_trylock ++ call __compat_down_trylock + popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ecx +@@ -91,9 +91,9 @@ + ENDFRAME + ret + CFI_ENDPROC +- END(__down_failed_trylock) ++ END(__compat_down_failed_trylock) + +-ENTRY(__up_wakeup) ++ENTRY(__compat_up_wakeup) + CFI_STARTPROC + FRAME + pushl %edx +@@ -102,7 +102,7 @@ + pushl %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 +- call __up ++ call __compat_up + popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ecx +@@ -112,7 +112,7 @@ + ENDFRAME + ret + CFI_ENDPROC +- END(__up_wakeup) ++ END(__compat_up_wakeup) + + /* + * rw spinlock fallbacks +diff -Nur custom-source-rt.orig/arch/i386/mach-default/setup.c custom-source-rt/arch/i386/mach-default/setup.c +--- custom-source-rt.orig/arch/i386/mach-default/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mach-default/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -35,7 +35,7 @@ + /* + * IRQ2 is cascade interrupt to second interrupt controller + */ +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; ++static struct irqaction irq2 = { no_action, IRQF_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; + + /** + * intr_init_hook - post gate setup interrupt initialisation +@@ -81,7 +81,7 @@ + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +diff -Nur custom-source-rt.orig/arch/i386/mach-visws/visws_apic.c custom-source-rt/arch/i386/mach-visws/visws_apic.c +--- custom-source-rt.orig/arch/i386/mach-visws/visws_apic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mach-visws/visws_apic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -257,11 +257,13 @@ + static struct irqaction master_action = { + .handler = piix4_master_intr, + .name = "PIIX4-8259", ++ .flags = IRQF_NODELAY, + }; + + static struct irqaction cascade_action = { + .handler = no_action, + .name = "cascade", ++ .flags = IRQF_NODELAY, + }; + + +diff -Nur custom-source-rt.orig/arch/i386/mach-voyager/setup.c custom-source-rt/arch/i386/mach-voyager/setup.c +--- custom-source-rt.orig/arch/i386/mach-voyager/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mach-voyager/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -18,7 +18,7 @@ + /* + * IRQ2 is cascade interrupt to second interrupt controller + */ +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; ++static struct irqaction irq2 = { no_action, IRQF_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; + + void __init intr_init_hook(void) + { +@@ -42,7 +42,7 @@ + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +diff -Nur custom-source-rt.orig/arch/i386/mm/fault.c custom-source-rt/arch/i386/mm/fault.c +--- custom-source-rt.orig/arch/i386/mm/fault.c 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/arch/i386/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -296,8 +296,8 @@ + * bit 3 == 1 means use of reserved bit detected + * bit 4 == 1 means fault was an instruction fetch + */ +-fastcall void __kprobes do_page_fault(struct pt_regs *regs, +- unsigned long error_code) ++fastcall notrace void __kprobes do_page_fault(struct pt_regs *regs, ++ unsigned long error_code) + { + struct task_struct *tsk; + struct mm_struct *mm; +@@ -307,6 +307,7 @@ + + /* get the address */ + address = read_cr2(); ++ trace_special(regs->eip, error_code, address); + + tsk = current; + +@@ -351,7 +352,7 @@ + * If we're in an interrupt, have no user context or are running in an + * atomic region then we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (in_atomic() || !mm || current->pagefault_disabled) + goto bad_area_nosemaphore; + + /* When running in the kernel we expect faults to occur only to +@@ -489,6 +490,9 @@ + nr = (address - idt_descr.address) >> 3; + + if (nr == 6) { ++ stop_trace(); ++ user_trace_stop(); ++ zap_rt_locks(); + do_invalid_op(regs, 0); + return; + } +diff -Nur custom-source-rt.orig/arch/i386/mm/highmem.c custom-source-rt/arch/i386/mm/highmem.c +--- custom-source-rt.orig/arch/i386/mm/highmem.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mm/highmem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -3,9 +3,9 @@ + + void *kmap(struct page *page) + { +- might_sleep(); + if (!PageHighMem(page)) + return page_address(page); ++ might_sleep(); + return kmap_high(page); + } + +@@ -18,6 +18,26 @@ + kunmap_high(page); + } + ++void kunmap_virt(void *ptr) ++{ ++ struct page *page; ++ ++ if ((unsigned long)ptr < PKMAP_ADDR(0)) ++ return; ++ page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); ++ kunmap(page); ++} ++ ++struct page *kmap_to_page(void *ptr) ++{ ++ struct page *page; ++ ++ if ((unsigned long)ptr < PKMAP_ADDR(0)) ++ return virt_to_page(ptr); ++ page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); ++ return page; ++} ++ + /* + * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because + * no global lock is needed and because the kmap code must perform a global TLB +@@ -26,16 +46,16 @@ + * However when holding an atomic kmap is is not legal to sleep, so atomic + * kmaps are appropriate for short, tight code paths only. + */ +-void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) ++void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) + { + enum fixed_addresses idx; + unsigned long vaddr; + +- /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ ++ preempt_disable(); + pagefault_disable(); + + idx = type + KM_TYPE_NR*smp_processor_id(); +- BUG_ON(!pte_none(*(kmap_pte-idx))); ++ WARN_ON_ONCE(!pte_none(*(kmap_pte-idx))); + + if (!PageHighMem(page)) + return page_address(page); +@@ -47,12 +67,12 @@ + return (void*) vaddr; + } + +-void *kmap_atomic(struct page *page, enum km_type type) ++void *__kmap_atomic(struct page *page, enum km_type type) + { + return kmap_atomic_prot(page, type, kmap_prot); + } + +-void kunmap_atomic(void *kvaddr, enum km_type type) ++void __kunmap_atomic(void *kvaddr, enum km_type type) + { + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); +@@ -74,16 +94,18 @@ + + arch_flush_lazy_mmu_mode(); + pagefault_enable(); ++ preempt_enable(); + } + + /* This is the same as kmap_atomic() but can map memory that doesn't + * have a struct page associated with it. + */ +-void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) ++void *__kmap_atomic_pfn(unsigned long pfn, enum km_type type) + { + enum fixed_addresses idx; + unsigned long vaddr; + ++ preempt_disable(); + pagefault_disable(); + + idx = type + KM_TYPE_NR*smp_processor_id(); +@@ -94,7 +116,7 @@ + return (void*) vaddr; + } + +-struct page *kmap_atomic_to_page(void *ptr) ++struct page *__kmap_atomic_to_page(void *ptr) + { + unsigned long idx, vaddr = (unsigned long)ptr; + pte_t *pte; +@@ -109,6 +131,7 @@ + + EXPORT_SYMBOL(kmap); + EXPORT_SYMBOL(kunmap); +-EXPORT_SYMBOL(kmap_atomic); +-EXPORT_SYMBOL(kunmap_atomic); +-EXPORT_SYMBOL(kmap_atomic_to_page); ++EXPORT_SYMBOL(kunmap_virt); ++EXPORT_SYMBOL(__kmap_atomic); ++EXPORT_SYMBOL(__kunmap_atomic); ++EXPORT_SYMBOL(__kmap_atomic_to_page); +diff -Nur custom-source-rt.orig/arch/i386/mm/init.c custom-source-rt/arch/i386/mm/init.c +--- custom-source-rt.orig/arch/i386/mm/init.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -47,7 +47,7 @@ + + unsigned int __VMALLOC_RESERVE = 128 << 20; + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + unsigned long highstart_pfn, highend_pfn; + + static int noinline do_test_wp_bit(void); +@@ -193,7 +193,7 @@ + return 0; + } + +-int page_is_ram(unsigned long pagenr) ++int notrace page_is_ram(unsigned long pagenr) + { + int i; + unsigned long addr, end; +diff -Nur custom-source-rt.orig/arch/i386/mm/pgtable.c custom-source-rt/arch/i386/mm/pgtable.c +--- custom-source-rt.orig/arch/i386/mm/pgtable.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/mm/pgtable.c 2007-10-02 17:31:08.000000000 +0000 +@@ -208,7 +208,7 @@ + * vmalloc faults work because attached pagetables are never freed. + * -- wli + */ +-DEFINE_SPINLOCK(pgd_lock); ++DEFINE_RAW_SPINLOCK(pgd_lock); + struct page *pgd_list; + + static inline void pgd_list_add(pgd_t *pgd) +diff -Nur custom-source-rt.orig/arch/i386/oprofile/Kconfig custom-source-rt/arch/i386/oprofile/Kconfig +--- custom-source-rt.orig/arch/i386/oprofile/Kconfig 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/oprofile/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -15,3 +15,6 @@ + + If unsure, say N. + ++config PROFILE_NMI ++ bool ++ default y +diff -Nur custom-source-rt.orig/arch/i386/pci/Makefile custom-source-rt/arch/i386/pci/Makefile +--- custom-source-rt.orig/arch/i386/pci/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/pci/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -4,8 +4,9 @@ + obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o mmconfig-shared.o + obj-$(CONFIG_PCI_DIRECT) += direct.o + ++obj-$(CONFIG_ACPI) += acpi.o ++ + pci-y := fixup.o +-pci-$(CONFIG_ACPI) += acpi.o + pci-y += legacy.o irq.o + + pci-$(CONFIG_X86_VISWS) := visws.o fixup.o +diff -Nur custom-source-rt.orig/arch/i386/pci/common.c custom-source-rt/arch/i386/pci/common.c +--- custom-source-rt.orig/arch/i386/pci/common.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/pci/common.c 2007-10-02 17:31:08.000000000 +0000 +@@ -51,7 +51,7 @@ + * This interrupt-safe spinlock protects all accesses to PCI + * configuration space. + */ +-DEFINE_SPINLOCK(pci_config_lock); ++DEFINE_RAW_SPINLOCK(pci_config_lock); + + /* + * Several buggy motherboards address only 16 devices and mirror +diff -Nur custom-source-rt.orig/arch/i386/pci/direct.c custom-source-rt/arch/i386/pci/direct.c +--- custom-source-rt.orig/arch/i386/pci/direct.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/pci/direct.c 2007-10-02 17:31:08.000000000 +0000 +@@ -220,16 +220,23 @@ + unsigned int tmp; + int works = 0; + +- local_irq_save(flags); ++ spin_lock_irqsave(&pci_config_lock, flags); + + outb(0x01, 0xCFB); + tmp = inl(0xCF8); + outl(0x80000000, 0xCF8); +- if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { +- works = 1; ++ ++ if (inl(0xCF8) == 0x80000000) { ++ spin_unlock_irqrestore(&pci_config_lock, flags); ++ ++ if (pci_sanity_check(&pci_direct_conf1)) ++ works = 1; ++ ++ spin_lock_irqsave(&pci_config_lock, flags); + } + outl(tmp, 0xCF8); +- local_irq_restore(flags); ++ ++ spin_unlock_irqrestore(&pci_config_lock, flags); + + return works; + } +@@ -239,17 +246,19 @@ + unsigned long flags; + int works = 0; + +- local_irq_save(flags); ++ spin_lock_irqsave(&pci_config_lock, flags); + + outb(0x00, 0xCFB); + outb(0x00, 0xCF8); + outb(0x00, 0xCFA); +- if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && +- pci_sanity_check(&pci_direct_conf2)) { +- works = 1; +- } + +- local_irq_restore(flags); ++ if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) { ++ spin_unlock_irqrestore(&pci_config_lock, flags); ++ ++ if (pci_sanity_check(&pci_direct_conf2)) ++ works = 1; ++ } else ++ spin_unlock_irqrestore(&pci_config_lock, flags); + + return works; + } +diff -Nur custom-source-rt.orig/arch/i386/pci/pci.h custom-source-rt/arch/i386/pci/pci.h +--- custom-source-rt.orig/arch/i386/pci/pci.h 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/i386/pci/pci.h 2007-10-02 17:31:08.000000000 +0000 +@@ -78,7 +78,7 @@ + extern unsigned int pcibios_irq_mask; + + extern int pcibios_scanned; +-extern spinlock_t pci_config_lock; ++extern raw_spinlock_t pci_config_lock; + + extern int (*pcibios_enable_irq)(struct pci_dev *dev); + extern void (*pcibios_disable_irq)(struct pci_dev *dev); +diff -Nur custom-source-rt.orig/arch/ia64/Kconfig custom-source-rt/arch/ia64/Kconfig +--- custom-source-rt.orig/arch/ia64/Kconfig 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -44,6 +44,7 @@ + + config RWSEM_XCHGADD_ALGORITHM + bool ++ depends on !PREEMPT_RT + default y + + config ARCH_HAS_ILOG2_U32 +@@ -271,6 +272,69 @@ + + If you don't know what to do here, say N. + ++ ++config GENERIC_TIME ++ bool ++ default y ++ ++config HIGH_RES_TIMERS ++ bool "High-Resolution Timers" ++ help ++ ++ POSIX timers are available by default. This option enables ++ high-resolution POSIX timers. With this option the resolution ++ is at least 1 microsecond. High resolution is not free. If ++ enabled this option will add a small overhead each time a ++ timer expires that is not on a 1/HZ tick boundary. If no such ++ timers are used the overhead is nil. ++ ++ This option enables two additional POSIX CLOCKS, ++ CLOCK_REALTIME_HR and CLOCK_MONOTONIC_HR. Note that this ++ option does not change the resolution of CLOCK_REALTIME or ++ CLOCK_MONOTONIC which remain at 1/HZ resolution. ++ ++config HIGH_RES_RESOLUTION ++ int "High-Resolution-Timer resolution (nanoseconds)" ++ depends on HIGH_RES_TIMERS ++ default 1000 ++ help ++ ++ This sets the resolution of timers accessed with ++ CLOCK_REALTIME_HR and CLOCK_MONOTONIC_HR. Too ++ fine a resolution (small a number) will usually not ++ be observable due to normal system latencies. For an ++ 800 MHZ processor about 10,000 is the recommended maximum ++ (smallest number). If you don't need that sort of resolution, ++ higher numbers may generate less overhead. ++ ++choice ++ prompt "Clock source" ++ depends on HIGH_RES_TIMERS ++ default HIGH_RES_TIMER_ITC ++ help ++ This option allows you to choose the hardware source in charge ++ of generating high precision interruptions on your system. ++ On IA-64 these are: ++ ++ ++ ITC Interval Time Counter 1/CPU clock ++ HPET High Precision Event Timer ~ (XXX:have to check the spec) ++ ++ The ITC timer is available on all the ia64 computers because ++ it is integrated directly into the processor. However it may not ++ give correct results on MP machines with processors running ++ at different clock rates. In this case you may want to use ++ the HPET if available on your machine. ++ ++ ++config HIGH_RES_TIMER_ITC ++ bool "Interval Time Counter/ITC" ++ ++config HIGH_RES_TIMER_HPET ++ bool "High Precision Event Timer/HPET" ++ ++endchoice ++ + config NR_CPUS + int "Maximum number of CPUs (2-1024)" + range 2 1024 +@@ -323,17 +387,15 @@ + This option it useful to enable this feature on older BIOS's as well. + You can also enable this by using boot command line option force_cpei=1. + +-config PREEMPT +- bool "Preemptible Kernel" +- help +- This option reduces the latency of the kernel when reacting to +- real-time or interactive events by allowing a low priority process to +- be preempted even if it is in kernel mode executing a system call. +- This allows applications to run more reliably even when the system is +- under load. ++source "kernel/Kconfig.preempt" + +- Say Y here if you are building a kernel for a desktop, embedded +- or real-time system. Say N if you are unsure. ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ depends on PREEMPT_RT ++ default y ++ ++config PREEMPT ++ def_bool y if (PREEMPT_RT || PREEMPT_SOFTIRQS || PREEMPT_HARDIRQS || PREEMPT_VOLUNTARY || PREEMPT_DESKTOP) + + source "mm/Kconfig" + +diff -Nur custom-source-rt.orig/arch/ia64/kernel/asm-offsets.c custom-source-rt/arch/ia64/kernel/asm-offsets.c +--- custom-source-rt.orig/arch/ia64/kernel/asm-offsets.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/asm-offsets.c 2007-10-02 17:31:08.000000000 +0000 +@@ -255,6 +255,7 @@ + offsetof (struct pal_min_state_area_s, pmsa_xip)); + BLANK(); + ++#ifdef CONFIG_TIME_INTERPOLATION + /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */ + DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr)); + DEFINE(IA64_TIME_INTERPOLATOR_SOURCE_OFFSET, offsetof (struct time_interpolator, source)); +@@ -269,4 +270,5 @@ + DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64); + DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32); + DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec)); ++#endif + } +diff -Nur custom-source-rt.orig/arch/ia64/kernel/entry.S custom-source-rt/arch/ia64/kernel/entry.S +--- custom-source-rt.orig/arch/ia64/kernel/entry.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -1098,23 +1098,24 @@ + st8 [r2]=r8 + st8 [r3]=r10 + .work_pending: +- tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? ++ tbit.nz p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? ++(p6) br.cond.sptk.few .needresched ++ tbit.z p6,p0=r31,TIF_NEED_RESCHED_DELAYED // current_thread_info()->need_resched_delayed==0? + (p6) br.cond.sptk.few .notify +-#ifdef CONFIG_PREEMPT +-(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 ++ ++.needresched: ++ ++(pKStk) br.cond.sptk.many .fromkernel + ;; +-(pKStk) st4 [r20]=r21 + ssm psr.i // enable interrupts +-#endif + br.call.spnt.many rp=schedule +-.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 +- rsm psr.i // disable interrupts +- ;; +-#ifdef CONFIG_PREEMPT +-(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 ++.ret9a: rsm psr.i // disable interrupts + ;; +-(pKStk) st4 [r20]=r0 // preempt_count() <- 0 +-#endif ++ br.cond.sptk.many .endpreemptdep ++.fromkernel: ++ br.call.spnt.many rp=preempt_schedule_irq ++.ret9b: rsm psr.i // disable interrupts ++.endpreemptdep: + (pLvSys)br.cond.sptk.few .work_pending_syscall_end + br.cond.sptk.many .work_processed_kernel // re-check + +diff -Nur custom-source-rt.orig/arch/ia64/kernel/fsys.S custom-source-rt/arch/ia64/kernel/fsys.S +--- custom-source-rt.orig/arch/ia64/kernel/fsys.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/fsys.S 2007-10-02 17:31:08.000000000 +0000 +@@ -26,6 +26,7 @@ + + #include "entry.h" + ++#ifdef CONFIG_TIME_INTERPOLATION + /* + * See Documentation/ia64/fsys.txt for details on fsyscalls. + * +@@ -350,6 +351,26 @@ + br.many .gettime + END(fsys_clock_gettime) + ++ ++#else // !CONFIG_TIME_INTERPOLATION ++ ++# define fsys_gettimeofday 0 ++# define fsys_clock_gettime 0 ++ ++.fail_einval: ++ mov r8 = EINVAL ++ mov r10 = -1 ++ FSYS_RETURN ++ ++.fail_efault: ++ mov r8 = EFAULT ++ mov r10 = -1 ++ FSYS_RETURN ++ ++#endif ++ ++ ++ + /* + * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize). + */ +diff -Nur custom-source-rt.orig/arch/ia64/kernel/iosapic.c custom-source-rt/arch/ia64/kernel/iosapic.c +--- custom-source-rt.orig/arch/ia64/kernel/iosapic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/iosapic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -111,7 +111,7 @@ + (PAGE_SIZE / sizeof(struct iosapic_rte_info)) + #define RTE_PREALLOCATED (1) + +-static DEFINE_SPINLOCK(iosapic_lock); ++static DEFINE_RAW_SPINLOCK(iosapic_lock); + + /* + * These tables map IA-64 vectors to the IOSAPIC pin that generates this +@@ -429,6 +429,34 @@ + return 0; + } + ++/* ++ * In the preemptible case mask the IRQ first then handle it and ack it. ++ */ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ ++static void ++iosapic_ack_level_irq (unsigned int irq) ++{ ++ ia64_vector vec = irq_to_vector(irq); ++ struct iosapic_rte_info *rte; ++ ++ move_irq(irq); ++ mask_irq(irq); ++ list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) ++ iosapic_eoi(rte->addr, vec); ++} ++ ++static void ++iosapic_end_level_irq (unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & IRQ_INPROGRESS)) ++ unmask_irq(irq); ++} ++ ++#else /* !CONFIG_PREEMPT_HARDIRQS */ ++ ++#define iosapic_ack_level_irq nop ++ + static void + iosapic_end_level_irq (unsigned int irq) + { +@@ -440,10 +468,12 @@ + iosapic_eoi(rte->addr, vec); + } + ++ ++#endif ++ + #define iosapic_shutdown_level_irq mask_irq + #define iosapic_enable_level_irq unmask_irq + #define iosapic_disable_level_irq mask_irq +-#define iosapic_ack_level_irq nop + + struct irq_chip irq_type_iosapic_level = { + .name = "IO-SAPIC-level", +diff -Nur custom-source-rt.orig/arch/ia64/kernel/mca.c custom-source-rt/arch/ia64/kernel/mca.c +--- custom-source-rt.orig/arch/ia64/kernel/mca.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/mca.c 2007-10-02 17:31:08.000000000 +0000 +@@ -320,7 +320,7 @@ + + typedef struct ia64_state_log_s + { +- spinlock_t isl_lock; ++ raw_spinlock_t isl_lock; + int isl_index; + unsigned long isl_count; + ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */ +diff -Nur custom-source-rt.orig/arch/ia64/kernel/perfmon.c custom-source-rt/arch/ia64/kernel/perfmon.c +--- custom-source-rt.orig/arch/ia64/kernel/perfmon.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/perfmon.c 2007-10-02 17:31:08.000000000 +0000 +@@ -280,7 +280,7 @@ + */ + + typedef struct pfm_context { +- spinlock_t ctx_lock; /* context protection */ ++ raw_spinlock_t ctx_lock; /* context protection */ + + pfm_context_flags_t ctx_flags; /* bitmask of flags (block reason incl.) */ + unsigned int ctx_state; /* state: active/inactive (no bitfield) */ +@@ -369,7 +369,7 @@ + * mostly used to synchronize between system wide and per-process + */ + typedef struct { +- spinlock_t pfs_lock; /* lock the structure */ ++ raw_spinlock_t pfs_lock; /* lock the structure */ + + unsigned int pfs_task_sessions; /* number of per task sessions */ + unsigned int pfs_sys_sessions; /* number of per system wide sessions */ +@@ -510,7 +510,7 @@ + static struct proc_dir_entry *perfmon_dir; + static pfm_uuid_t pfm_null_uuid = {0,}; + +-static spinlock_t pfm_buffer_fmt_lock; ++static raw_spinlock_t pfm_buffer_fmt_lock; + static LIST_HEAD(pfm_buffer_fmt_list); + + static pmu_config_t *pmu_conf; +diff -Nur custom-source-rt.orig/arch/ia64/kernel/process.c custom-source-rt/arch/ia64/kernel/process.c +--- custom-source-rt.orig/arch/ia64/kernel/process.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -94,6 +94,9 @@ + void + dump_stack (void) + { ++ if (irqs_disabled()) { ++ printk("Uh oh.. entering dump_stack() with irqs disabled.\n"); ++ } + show_stack(NULL, NULL); + } + +@@ -197,7 +200,7 @@ + default_idle (void) + { + local_irq_enable(); +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + if (can_do_pal_halt) + safe_halt(); + else +@@ -281,7 +284,7 @@ + current_thread_info()->status |= TS_POLLING; + } + +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + void (*idle)(void); + #ifdef CONFIG_SMP + min_xtp(); +@@ -303,10 +306,11 @@ + normal_xtp(); + #endif + } +- preempt_enable_no_resched(); +- schedule(); ++ __preempt_enable_no_resched(); ++ __schedule(); ++ + preempt_disable(); +- check_pgt_cache(); ++ + if (cpu_is_offline(cpu)) + play_dead(); + } +diff -Nur custom-source-rt.orig/arch/ia64/kernel/sal.c custom-source-rt/arch/ia64/kernel/sal.c +--- custom-source-rt.orig/arch/ia64/kernel/sal.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/sal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -18,7 +18,7 @@ + #include + #include + +- __cacheline_aligned DEFINE_SPINLOCK(sal_lock); ++ __cacheline_aligned DEFINE_RAW_SPINLOCK(sal_lock); + unsigned long sal_platform_features; + + unsigned short sal_revision; +diff -Nur custom-source-rt.orig/arch/ia64/kernel/salinfo.c custom-source-rt/arch/ia64/kernel/salinfo.c +--- custom-source-rt.orig/arch/ia64/kernel/salinfo.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/salinfo.c 2007-10-02 17:31:08.000000000 +0000 +@@ -140,7 +140,7 @@ + + struct salinfo_data { + cpumask_t cpu_event; /* which cpus have outstanding events */ +- struct semaphore mutex; ++ struct compat_semaphore mutex; + u8 *log_buffer; + u64 log_size; + u8 *oemdata; /* decoded oem data */ +@@ -156,8 +156,8 @@ + + static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)]; + +-static DEFINE_SPINLOCK(data_lock); +-static DEFINE_SPINLOCK(data_saved_lock); ++static DEFINE_RAW_SPINLOCK(data_lock); ++static DEFINE_RAW_SPINLOCK(data_saved_lock); + + /** salinfo_platform_oemdata - optional callback to decode oemdata from an error + * record. +diff -Nur custom-source-rt.orig/arch/ia64/kernel/semaphore.c custom-source-rt/arch/ia64/kernel/semaphore.c +--- custom-source-rt.orig/arch/ia64/kernel/semaphore.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -40,12 +40,12 @@ + */ + + void +-__up (struct semaphore *sem) ++__up (struct compat_semaphore *sem) + { + wake_up(&sem->wait); + } + +-void __sched __down (struct semaphore *sem) ++void __sched __down (struct compat_semaphore *sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -82,7 +82,7 @@ + tsk->state = TASK_RUNNING; + } + +-int __sched __down_interruptible (struct semaphore * sem) ++int __sched __down_interruptible (struct compat_semaphore * sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -142,7 +142,7 @@ + * count. + */ + int +-__down_trylock (struct semaphore *sem) ++__down_trylock (struct compat_semaphore *sem) + { + unsigned long flags; + int sleepers; +diff -Nur custom-source-rt.orig/arch/ia64/kernel/setup.c custom-source-rt/arch/ia64/kernel/setup.c +--- custom-source-rt.orig/arch/ia64/kernel/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -805,7 +805,6 @@ + get_max_cacheline_size (void) + { + unsigned long line_size, max = 1; +- unsigned int cache_size = 0; + u64 l, levels, unique_caches; + pal_cache_config_info_t cci; + s64 status; +@@ -835,8 +834,6 @@ + line_size = 1 << cci.pcci_line_size; + if (line_size > max) + max = line_size; +- if (cache_size < cci.pcci_cache_size) +- cache_size = cci.pcci_cache_size; + if (!cci.pcci_unified) { + status = ia64_pal_cache_config_info(l, + /* cache_type (instruction)= */ 1, +@@ -853,9 +850,6 @@ + ia64_i_cache_stride_shift = cci.pcci_stride; + } + out: +-#ifdef CONFIG_SMP +- max_cache_size = max(max_cache_size, cache_size); +-#endif + if (max > ia64_max_cacheline_size) + ia64_max_cacheline_size = max; + } +diff -Nur custom-source-rt.orig/arch/ia64/kernel/signal.c custom-source-rt/arch/ia64/kernel/signal.c +--- custom-source-rt.orig/arch/ia64/kernel/signal.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -446,6 +446,14 @@ + long errno = scr->pt.r8; + # define ERR_CODE(c) (IS_IA32_PROCESS(&scr->pt) ? -(c) : (c)) + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + /* + * In the ia64_leave_kernel code path, we want the common case to go fast, which + * is why we may in certain cases get here from kernel mode. Just return without +diff -Nur custom-source-rt.orig/arch/ia64/kernel/smp.c custom-source-rt/arch/ia64/kernel/smp.c +--- custom-source-rt.orig/arch/ia64/kernel/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -261,6 +261,22 @@ + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ unsigned int cpu; ++ ++ for_each_online_cpu(cpu) { ++ if (cpu != smp_processor_id()) ++ platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, ++ IA64_IPI_DM_INT, 0); ++ } ++} ++ ++/* + * Called with preemption disabled. + */ + static void +diff -Nur custom-source-rt.orig/arch/ia64/kernel/smpboot.c custom-source-rt/arch/ia64/kernel/smpboot.c +--- custom-source-rt.orig/arch/ia64/kernel/smpboot.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/smpboot.c 2007-10-02 17:31:08.000000000 +0000 +@@ -370,6 +370,8 @@ + { + } + ++extern void register_itc_clockevent(void); ++ + static void __cpuinit + smp_callin (void) + { +@@ -444,6 +446,7 @@ + #ifdef CONFIG_IA32_SUPPORT + ia32_gdt_init(); + #endif ++ register_itc_clockevent(); + + /* + * Allow the master to continue. +diff -Nur custom-source-rt.orig/arch/ia64/kernel/time.c custom-source-rt/arch/ia64/kernel/time.c +--- custom-source-rt.orig/arch/ia64/kernel/time.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -54,6 +54,7 @@ + + platform_timer_interrupt(irq, dev_id); + ++#if 0 + new_itm = local_cpu_data->itm_next; + + if (!time_after(ia64_get_itc(), new_itm)) +@@ -61,29 +62,48 @@ + ia64_get_itc(), new_itm); + + profile_tick(CPU_PROFILING); ++#endif ++ ++ if (time_after(ia64_get_itc(), local_cpu_data->itm_tick_next)) { + +- while (1) { +- update_process_times(user_mode(get_irq_regs())); ++ unsigned long new_tick_itm; ++ new_tick_itm = local_cpu_data->itm_tick_next; + +- new_itm += local_cpu_data->itm_delta; ++ profile_tick(CPU_PROFILING, get_irq_regs()); + +- if (smp_processor_id() == time_keeper_id) { +- /* +- * Here we are in the timer irq handler. We have irqs locally +- * disabled, but we don't know if the timer_bh is running on +- * another CPU. We need to avoid to SMP race by acquiring the +- * xtime_lock. +- */ +- write_seqlock(&xtime_lock); +- do_timer(1); +- local_cpu_data->itm_next = new_itm; +- write_sequnlock(&xtime_lock); +- } else +- local_cpu_data->itm_next = new_itm; ++ while (1) { ++ update_process_times(user_mode(get_irq_regs())); ++ ++ new_tick_itm += local_cpu_data->itm_tick_delta; ++ ++ if (smp_processor_id() == time_keeper_id) { ++ /* ++ * Here we are in the timer irq handler. We have irqs locally ++ * disabled, but we don't know if the timer_bh is running on ++ * another CPU. We need to avoid to SMP race by acquiring the ++ * xtime_lock. ++ */ ++ write_seqlock(&xtime_lock); ++ do_timer(get_irq_regs()); ++ local_cpu_data->itm_tick_next = new_tick_itm; ++ write_sequnlock(&xtime_lock); ++ } else ++ local_cpu_data->itm_tick_next = new_tick_itm; ++ ++ if (time_after(new_tick_itm, ia64_get_itc())) ++ break; ++ } ++ } + +- if (time_after(new_itm, ia64_get_itc())) +- break; ++ if (time_after(ia64_get_itc(), local_cpu_data->itm_timer_next)) { ++ if (itc_clockevent.event_handler) ++ itc_clockevent.event_handler(get_irq_regs()); + ++ // FIXME, really, please ++ new_itm = local_cpu_data->itm_tick_next; ++ ++ if (time_after(new_itm, local_cpu_data->itm_timer_next)) ++ new_itm = local_cpu_data->itm_timer_next; + /* + * Allow IPIs to interrupt the timer loop. + */ +@@ -101,8 +121,8 @@ + * too fast (with the potentially devastating effect + * of losing monotony of time). + */ +- while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2)) +- new_itm += local_cpu_data->itm_delta; ++ while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_tick_delta/2)) ++ new_itm += local_cpu_data->itm_tick_delta; + ia64_set_itm(new_itm); + /* double check, in case we got hit by a (slow) PMI: */ + } while (time_after_eq(ia64_get_itc(), new_itm)); +@@ -121,7 +141,7 @@ + /* arrange for the cycle counter to generate a timer interrupt: */ + ia64_set_itv(IA64_TIMER_VECTOR); + +- delta = local_cpu_data->itm_delta; ++ delta = local_cpu_data->itm_tick_delta; + /* + * Stagger the timer tick for each CPU so they don't occur all at (almost) the + * same time: +@@ -130,8 +150,8 @@ + unsigned long hi = 1UL << ia64_fls(cpu); + shift = (2*(cpu - hi) + 1) * delta/hi/2; + } +- local_cpu_data->itm_next = ia64_get_itc() + delta + shift; +- ia64_set_itm(local_cpu_data->itm_next); ++ local_cpu_data->itm_tick_next = ia64_get_itc() + delta + shift; ++ ia64_set_itm(local_cpu_data->itm_tick_next); + } + + static int nojitter; +@@ -189,7 +209,7 @@ + + itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; + +- local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; ++ local_cpu_data->itm_tick_delta = (itc_freq + HZ/2) / HZ; + printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, " + "ITC freq=%lu.%03luMHz", smp_processor_id(), + platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, +@@ -209,6 +229,7 @@ + local_cpu_data->nsec_per_cyc = ((NSEC_PER_SEC<itc_freq; + itc_interpolator.drift = itc_drift; +@@ -227,6 +248,7 @@ + #endif + register_time_interpolator(&itc_interpolator); + } ++#endif + + /* Setup the CPU local timer tick */ + ia64_cpu_local_tick(); +@@ -234,7 +256,7 @@ + + static struct irqaction timer_irqaction = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_IRQPOLL, ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NODELAY, + .name = "timer" + }; + +@@ -255,6 +277,8 @@ + * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). + */ + set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); ++ register_itc_clocksource(); ++ register_itc_clockevent(); + } + + /* +diff -Nur custom-source-rt.orig/arch/ia64/kernel/traps.c custom-source-rt/arch/ia64/kernel/traps.c +--- custom-source-rt.orig/arch/ia64/kernel/traps.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -39,11 +39,11 @@ + die (const char *str, struct pt_regs *regs, long err) + { + static struct { +- spinlock_t lock; ++ raw_spinlock_t lock; + u32 lock_owner; + int lock_owner_depth; + } die = { +- .lock = __SPIN_LOCK_UNLOCKED(die.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(die.lock), + .lock_owner = -1, + .lock_owner_depth = 0 + }; +@@ -180,7 +180,7 @@ + * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes + * care of clearing psr.dfh. + */ +-static inline void ++void + disabled_fph_fault (struct pt_regs *regs) + { + struct ia64_psr *psr = ia64_psr(regs); +@@ -199,7 +199,7 @@ + = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); + + if (ia64_is_local_fpu_owner(current)) { +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + return; + } + +@@ -219,7 +219,7 @@ + */ + psr->mfh = 1; + } +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + } + + static inline int +diff -Nur custom-source-rt.orig/arch/ia64/kernel/unwind.c custom-source-rt/arch/ia64/kernel/unwind.c +--- custom-source-rt.orig/arch/ia64/kernel/unwind.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/unwind.c 2007-10-02 17:31:08.000000000 +0000 +@@ -82,7 +82,7 @@ + typedef unsigned char unw_hash_index_t; + + static struct { +- spinlock_t lock; /* spinlock for unwind data */ ++ raw_spinlock_t lock; /* spinlock for unwind data */ + + /* list of unwind tables (one per load-module) */ + struct unw_table *tables; +@@ -146,7 +146,7 @@ + # endif + } unw = { + .tables = &unw.kernel_table, +- .lock = __SPIN_LOCK_UNLOCKED(unw.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(unw.lock), + .save_order = { + UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, + UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR +diff -Nur custom-source-rt.orig/arch/ia64/kernel/unwind_i.h custom-source-rt/arch/ia64/kernel/unwind_i.h +--- custom-source-rt.orig/arch/ia64/kernel/unwind_i.h 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/kernel/unwind_i.h 2007-10-02 17:31:08.000000000 +0000 +@@ -154,7 +154,7 @@ + unsigned long ip; /* ip this script is for */ + unsigned long pr_mask; /* mask of predicates script depends on */ + unsigned long pr_val; /* predicate values this script is for */ +- rwlock_t lock; ++ raw_rwlock_t lock; + unsigned int flags; /* see UNW_FLAG_* in unwind.h */ + unsigned short lru_chain; /* used for least-recently-used chain */ + unsigned short coll_chain; /* used for hash collisions */ +diff -Nur custom-source-rt.orig/arch/ia64/mm/init.c custom-source-rt/arch/ia64/mm/init.c +--- custom-source-rt.orig/arch/ia64/mm/init.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -37,7 +37,7 @@ + #include + #include + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + extern void ia64_tlb_init (void); + +diff -Nur custom-source-rt.orig/arch/ia64/mm/tlb.c custom-source-rt/arch/ia64/mm/tlb.c +--- custom-source-rt.orig/arch/ia64/mm/tlb.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ia64/mm/tlb.c 2007-10-02 17:31:08.000000000 +0000 +@@ -32,7 +32,7 @@ + } purge; + + struct ia64_ctx ia64_ctx = { +- .lock = __SPIN_LOCK_UNLOCKED(ia64_ctx.lock), ++ .lock = RAW_SPIN_LOCK_UNLOCKED(ia64_ctx.lock), + .next = 1, + .max_ctx = ~0U + }; +diff -Nur custom-source-rt.orig/arch/mips/Kconfig custom-source-rt/arch/mips/Kconfig +--- custom-source-rt.orig/arch/mips/Kconfig 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -259,6 +259,7 @@ + config MOMENCO_OCELOT + bool "Momentum Ocelot board" + select DMA_NONCOHERENT ++ select NO_SPINLOCK + select HW_HAS_PCI + select IRQ_CPU + select IRQ_CPU_RM7K +@@ -673,6 +674,7 @@ + + endmenu + ++ + config RWSEM_GENERIC_SPINLOCK + bool + default y +@@ -680,6 +682,10 @@ + config RWSEM_XCHGADD_ALGORITHM + bool + ++config ASM_SEMAPHORES ++ bool ++ default y ++ + config ARCH_HAS_ILOG2_U32 + bool + default n +@@ -738,6 +744,9 @@ + config DMA_NEED_PCI_MAP_STATE + bool + ++config NO_SPINLOCK ++ bool ++ + config EARLY_PRINTK + bool "Early printk" if EMBEDDED && DEBUG_KERNEL + depends on SYS_HAS_EARLY_PRINTK +@@ -1775,12 +1784,17 @@ + + If unsure, say Y. Only embedded should say N here. + +-endmenu +- +-config RWSEM_GENERIC_SPINLOCK ++config GENERIC_TIME + bool + default y + ++source "kernel/time/Kconfig" ++ ++config CPU_SPEED ++ int "CPU speed used for clocksource/clockevent calculations" ++ default 600 ++endmenu ++ + config LOCKDEP_SUPPORT + bool + default y +diff -Nur custom-source-rt.orig/arch/mips/kernel/Makefile custom-source-rt/arch/mips/kernel/Makefile +--- custom-source-rt.orig/arch/mips/kernel/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -5,7 +5,7 @@ + extra-y := head.o init_task.o vmlinux.lds + + obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ +- ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ ++ ptrace.o reset.o setup.o signal.o syscall.o \ + time.o topology.o traps.o unaligned.o + + binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ +@@ -14,6 +14,8 @@ + obj-$(CONFIG_STACKTRACE) += stacktrace.o + obj-$(CONFIG_MODULES) += mips_ksyms.o module.o + ++obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o ++ + obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o + obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o + obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o +diff -Nur custom-source-rt.orig/arch/mips/kernel/asm-offsets.c custom-source-rt/arch/mips/kernel/asm-offsets.c +--- custom-source-rt.orig/arch/mips/kernel/asm-offsets.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/asm-offsets.c 2007-10-02 17:31:08.000000000 +0000 +@@ -10,9 +10,11 @@ + */ + #include + #include ++#include + #include + #include + #include ++#include + + #include + #include +diff -Nur custom-source-rt.orig/arch/mips/kernel/entry.S custom-source-rt/arch/mips/kernel/entry.S +--- custom-source-rt.orig/arch/mips/kernel/entry.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -30,7 +30,7 @@ + .align 5 + #ifndef CONFIG_PREEMPT + FEXPORT(ret_from_exception) +- local_irq_disable # preempt stop ++ raw_local_irq_disable # preempt stop + b __ret_from_irq + #endif + FEXPORT(ret_from_irq) +@@ -41,7 +41,7 @@ + beqz t0, resume_kernel + + resume_userspace: +- local_irq_disable # make sure we dont miss an ++ raw_local_irq_disable # make sure we dont miss an + # interrupt setting need_resched + # between sampling and return + LONG_L a2, TI_FLAGS($28) # current->work +@@ -51,7 +51,9 @@ + + #ifdef CONFIG_PREEMPT + resume_kernel: +- local_irq_disable ++ raw_local_irq_disable ++ lw t0, kernel_preemption ++ beqz t0, restore_all + lw t0, TI_PRE_COUNT($28) + bnez t0, restore_all + need_resched: +@@ -61,7 +63,9 @@ + LONG_L t0, PT_STATUS(sp) # Interrupts off? + andi t0, 1 + beqz t0, restore_all ++ raw_local_irq_disable + jal preempt_schedule_irq ++ sw zero, TI_PRE_COUNT($28) + b need_resched + #endif + +@@ -69,7 +73,7 @@ + jal schedule_tail # a0 = struct task_struct *prev + + FEXPORT(syscall_exit) +- local_irq_disable # make sure need_resched and ++ raw_local_irq_disable # make sure need_resched and + # signals dont change between + # sampling and return + LONG_L a2, TI_FLAGS($28) # current->work +@@ -140,19 +144,21 @@ + .set at + + work_pending: +- andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS ++ # a2 is preloaded with TI_FLAGS ++ andi t0, a2, (_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beqz t0, work_notifysig + work_resched: ++ raw_local_irq_enable t0 + jal schedule + +- local_irq_disable # make sure need_resched and ++ raw_local_irq_disable # make sure need_resched and + # signals dont change between + # sampling and return + LONG_L a2, TI_FLAGS($28) + andi t0, a2, _TIF_WORK_MASK # is there any work to be done + # other than syscall tracing? + beqz t0, restore_all +- andi t0, a2, _TIF_NEED_RESCHED ++ andi t0, a2, (_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bnez t0, work_resched + + work_notifysig: # deal with pending signals and +@@ -168,7 +174,7 @@ + li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + and t0, a2 # a2 is preloaded with TI_FLAGS + beqz t0, work_pending # trace bit set? +- local_irq_enable # could let do_syscall_trace() ++ raw_local_irq_enable # could let do_syscall_trace() + # call schedule() instead + move a0, sp + li a1, 1 +diff -Nur custom-source-rt.orig/arch/mips/kernel/i8259.c custom-source-rt/arch/mips/kernel/i8259.c +--- custom-source-rt.orig/arch/mips/kernel/i8259.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/i8259.c 2007-10-02 17:31:08.000000000 +0000 +@@ -29,9 +29,9 @@ + */ + + static int i8259A_auto_eoi = -1; +-DEFINE_SPINLOCK(i8259A_lock); + /* some platforms call this... */ + void mask_and_ack_8259A(unsigned int); ++DEFINE_RAW_SPINLOCK(i8259A_lock); + + static struct irq_chip i8259A_chip = { + .name = "XT-PIC", +diff -Nur custom-source-rt.orig/arch/mips/kernel/module.c custom-source-rt/arch/mips/kernel/module.c +--- custom-source-rt.orig/arch/mips/kernel/module.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/module.c 2007-10-02 17:31:08.000000000 +0000 +@@ -40,7 +40,7 @@ + static struct mips_hi16 *mips_hi16_list; + + static LIST_HEAD(dbe_list); +-static DEFINE_SPINLOCK(dbe_lock); ++static DEFINE_RAW_SPINLOCK(dbe_lock); + + void *module_alloc(unsigned long size) + { +diff -Nur custom-source-rt.orig/arch/mips/kernel/process.c custom-source-rt/arch/mips/kernel/process.c +--- custom-source-rt.orig/arch/mips/kernel/process.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -50,7 +50,7 @@ + { + /* endless idle loop with no priority at all */ + while (1) { +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG + extern void smtc_idle_loop_hook(void); + +@@ -59,9 +59,11 @@ + if (cpu_wait) + (*cpu_wait)(); + } +- preempt_enable_no_resched(); +- schedule(); ++ local_irq_disable(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ local_irq_enable(); + } + } + +diff -Nur custom-source-rt.orig/arch/mips/kernel/scall32-o32.S custom-source-rt/arch/mips/kernel/scall32-o32.S +--- custom-source-rt.orig/arch/mips/kernel/scall32-o32.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/scall32-o32.S 2007-10-02 17:31:08.000000000 +0000 +@@ -73,7 +73,7 @@ + 1: sw v0, PT_R2(sp) # result + + o32_syscall_exit: +- local_irq_disable # make sure need_resched and ++ raw_local_irq_disable # make sure need_resched and + # signals dont change between + # sampling and return + lw a2, TI_FLAGS($28) # current->work +diff -Nur custom-source-rt.orig/arch/mips/kernel/scall64-64.S custom-source-rt/arch/mips/kernel/scall64-64.S +--- custom-source-rt.orig/arch/mips/kernel/scall64-64.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/scall64-64.S 2007-10-02 17:31:08.000000000 +0000 +@@ -72,7 +72,7 @@ + 1: sd v0, PT_R2(sp) # result + + n64_syscall_exit: +- local_irq_disable # make sure need_resched and ++ raw_local_irq_disable # make sure need_resched and + # signals dont change between + # sampling and return + LONG_L a2, TI_FLAGS($28) # current->work +diff -Nur custom-source-rt.orig/arch/mips/kernel/scall64-n32.S custom-source-rt/arch/mips/kernel/scall64-n32.S +--- custom-source-rt.orig/arch/mips/kernel/scall64-n32.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/scall64-n32.S 2007-10-02 17:31:08.000000000 +0000 +@@ -69,7 +69,7 @@ + sd v0, PT_R0(sp) # set flag for syscall restarting + 1: sd v0, PT_R2(sp) # result + +- local_irq_disable # make sure need_resched and ++ raw_local_irq_disable # make sure need_resched and + # signals dont change between + # sampling and return + LONG_L a2, TI_FLAGS($28) # current->work +diff -Nur custom-source-rt.orig/arch/mips/kernel/scall64-o32.S custom-source-rt/arch/mips/kernel/scall64-o32.S +--- custom-source-rt.orig/arch/mips/kernel/scall64-o32.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/scall64-o32.S 2007-10-02 17:31:08.000000000 +0000 +@@ -98,7 +98,7 @@ + 1: sd v0, PT_R2(sp) # result + + o32_syscall_exit: +- local_irq_disable # make need_resched and ++ raw_local_irq_disable # make need_resched and + # signals dont change between + # sampling and return + LONG_L a2, TI_FLAGS($28) +diff -Nur custom-source-rt.orig/arch/mips/kernel/semaphore.c custom-source-rt/arch/mips/kernel/semaphore.c +--- custom-source-rt.orig/arch/mips/kernel/semaphore.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -36,7 +36,7 @@ + * sem->count and sem->waking atomic. Scalability isn't an issue because + * this lock is used on UP only so it's just an empty variable. + */ +-static inline int __sem_update_count(struct semaphore *sem, int incr) ++static inline int __sem_update_count(struct compat_semaphore *sem, int incr) + { + int old_count, tmp; + +@@ -67,7 +67,7 @@ + : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) + : "r" (incr), "m" (sem->count)); + } else { +- static DEFINE_SPINLOCK(semaphore_lock); ++ static DEFINE_RAW_SPINLOCK(semaphore_lock); + unsigned long flags; + + spin_lock_irqsave(&semaphore_lock, flags); +@@ -80,7 +80,7 @@ + return old_count; + } + +-void __up(struct semaphore *sem) ++void __compat_up(struct compat_semaphore *sem) + { + /* + * Note that we incremented count in up() before we came here, +@@ -94,7 +94,7 @@ + wake_up(&sem->wait); + } + +-EXPORT_SYMBOL(__up); ++EXPORT_SYMBOL(__compat_up); + + /* + * Note that when we come in to __down or __down_interruptible, +@@ -104,7 +104,7 @@ + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. + */ +-void __sched __down(struct semaphore *sem) ++void __sched __compat_down(struct compat_semaphore *sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -133,9 +133,9 @@ + wake_up(&sem->wait); + } + +-EXPORT_SYMBOL(__down); ++EXPORT_SYMBOL(__compat_down); + +-int __sched __down_interruptible(struct semaphore * sem) ++int __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -165,4 +165,10 @@ + return retval; + } + +-EXPORT_SYMBOL(__down_interruptible); ++EXPORT_SYMBOL(__compat_down_interruptible); ++ ++int fastcall compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} ++EXPORT_SYMBOL(compat_sem_is_locked); +diff -Nur custom-source-rt.orig/arch/mips/kernel/signal.c custom-source-rt/arch/mips/kernel/signal.c +--- custom-source-rt.orig/arch/mips/kernel/signal.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -629,6 +629,10 @@ + siginfo_t info; + int signr; + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which is why we may in certain + * cases get here from kernel mode. Just return without doing anything +diff -Nur custom-source-rt.orig/arch/mips/kernel/signal32.c custom-source-rt/arch/mips/kernel/signal32.c +--- custom-source-rt.orig/arch/mips/kernel/signal32.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/signal32.c 2007-10-02 17:31:08.000000000 +0000 +@@ -656,6 +656,10 @@ + if (err) + goto give_sigsegv; + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * Arguments to signal handler: + * +diff -Nur custom-source-rt.orig/arch/mips/kernel/smp.c custom-source-rt/arch/mips/kernel/smp.c +--- custom-source-rt.orig/arch/mips/kernel/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -51,16 +51,6 @@ + EXPORT_SYMBOL(phys_cpu_present_map); + EXPORT_SYMBOL(cpu_online_map); + +-/* This happens early in bootup, can't really do it better */ +-static void smp_tune_scheduling (void) +-{ +- struct cache_desc *cd = ¤t_cpu_data.scache; +- unsigned long cachesize = cd->linesz * cd->sets * cd->ways; +- +- if (cachesize > max_cache_size) +- max_cache_size = cachesize; +-} +- + extern void __init calibrate_delay(void); + extern ATTRIB_NORET void cpu_idle(void); + +@@ -98,7 +88,22 @@ + cpu_idle(); + } + +-DEFINE_SPINLOCK(smp_call_lock); ++DEFINE_RAW_SPINLOCK(smp_call_lock); ++ ++/* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them. ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ int cpu = smp_processor_id(); ++ int i; ++ ++ for (i = 0; i < NR_CPUS; i++) ++ if (cpu_online(i) && i != cpu) ++ core_send_ipi(i, SMP_RESCHEDULE_YOURSELF); ++} + + struct call_data_struct *call_data; + +@@ -228,7 +233,6 @@ + { + init_new_context(current, &init_mm); + current_thread_info()->cpu = 0; +- smp_tune_scheduling(); + plat_prepare_cpus(max_cpus); + #ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +@@ -286,6 +290,8 @@ + return 0; + } + ++static DEFINE_RAW_SPINLOCK(tlbstate_lock); ++ + static void flush_tlb_all_ipi(void *info) + { + local_flush_tlb_all(); +@@ -343,6 +349,7 @@ + void flush_tlb_mm(struct mm_struct *mm) + { + preempt_disable(); ++ spin_lock(&tlbstate_lock); + + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + smp_on_other_tlbs(flush_tlb_mm_ipi, (void *)mm); +@@ -352,6 +359,7 @@ + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; + } ++ spin_unlock(&tlbstate_lock); + local_flush_tlb_mm(mm); + + preempt_enable(); +@@ -375,6 +383,8 @@ + struct mm_struct *mm = vma->vm_mm; + + preempt_disable(); ++ spin_lock(&tlbstate_lock); ++ + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + struct flush_tlb_data fd; + +@@ -388,6 +398,7 @@ + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; + } ++ spin_unlock(&tlbstate_lock); + local_flush_tlb_range(vma, start, end); + preempt_enable(); + } +@@ -418,6 +429,8 @@ + void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) + { + preempt_disable(); ++ spin_lock(&tlbstate_lock); ++ + if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { + struct flush_tlb_data fd; + +@@ -430,6 +443,7 @@ + if (smp_processor_id() != i) + cpu_context(i, vma->vm_mm) = 0; + } ++ spin_unlock(&tlbstate_lock); + local_flush_tlb_page(vma, page); + preempt_enable(); + } +diff -Nur custom-source-rt.orig/arch/mips/kernel/time.c custom-source-rt/arch/mips/kernel/time.c +--- custom-source-rt.orig/arch/mips/kernel/time.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -10,6 +10,11 @@ + * 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 implementation of High Res Timers uses two timers. One is the system ++ * timer. The second is used for the high res timers. The high res timers ++ * require the CPU to have count/compare registers. The mips_set_next_event() ++ * function schedules the next high res timer interrupt. + */ + #include + #include +@@ -23,6 +28,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -47,7 +53,27 @@ + /* + * forward reference + */ +-DEFINE_SPINLOCK(rtc_lock); ++DEFINE_RAW_SPINLOCK(rtc_lock); ++ ++/* any missed timer interrupts */ ++int missed_timer_count; ++ ++#ifdef CONFIG_HIGH_RES_TIMERS ++static void mips_set_next_event(unsigned long evt); ++static void mips_set_mode(int mode, void *priv); ++ ++static struct clock_event lapic_clockevent = { ++ .name = "mips clockevent interface", ++ .capabilities = CLOCK_CAP_NEXTEVT | CLOCK_CAP_PROFILE | ++ CLOCK_HAS_IRQHANDLER ++#ifdef CONFIG_SMP ++ | CLOCK_CAP_UPDATE ++#endif ++ , ++ .shift = 32, ++ .set_next_event = mips_set_next_event, ++}; ++#endif + + /* + * By default we provide the null RTC ops +@@ -56,6 +82,129 @@ + { + return mktime(2000, 1, 1, 0, 0, 0); + } ++#ifdef CONFIG_SMP ++/* ++ * We have to synchronize the master CPU with all the slave CPUs ++ */ ++static atomic_t cpus_started; ++static atomic_t cpus_ready; ++static atomic_t cpus_count; ++/* ++ * Master processor inits ++ */ ++static void sync_cpus_init(int v) ++{ ++ atomic_set(&cpus_count, 0); ++ mb(); ++ atomic_set(&cpus_started, v); ++ mb(); ++ atomic_set(&cpus_ready, v); ++ mb(); ++} ++ ++/* ++ * Called by the master processor ++ */ ++static void sync_cpus_master(int v) ++{ ++ atomic_set(&cpus_count, 0); ++ mb(); ++ atomic_set(&cpus_started, v); ++ mb(); ++ /* Wait here till all other CPUs are now ready */ ++ while (atomic_read(&cpus_count) != (num_online_cpus() -1) ) ++ mb(); ++ atomic_set(&cpus_ready, v); ++ mb(); ++} ++/* ++ * Called by the slave processors ++ */ ++static void sync_cpus_slave(int v) ++{ ++ /* Check if the master has been through this */ ++ while (atomic_read(&cpus_started) != v) ++ mb(); ++ atomic_inc(&cpus_count); ++ mb(); ++ while (atomic_read(&cpus_ready) != v) ++ mb(); ++} ++/* ++ * Called by the slave CPUs when done syncing the count register ++ * with the master processor ++ */ ++static void sync_cpus_slave_exit(int v) ++{ ++ while (atomic_read(&cpus_started) != v) ++ mb(); ++ atomic_inc(&cpus_count); ++ mb(); ++} ++ ++#define LOOPS 100 ++static u32 c0_count[NR_CPUS]; /* Count register per CPU */ ++static u32 c[NR_CPUS][LOOPS + 1]; /* Count register per CPU per loop for syncing */ ++ ++/* ++ * Slave processors execute this via IPI ++ */ ++static void sync_c0_count_slave(void *info) ++{ ++ int cpus = 1, loop, prev_count = 0, cpu = smp_processor_id(); ++ unsigned long flags; ++ u32 diff_count; /* CPU count registers are 32-bit */ ++ local_irq_save(flags); ++ ++ for(loop = 0; loop <= LOOPS; loop++) { ++ /* Sync with the Master processor */ ++ sync_cpus_slave(cpus++); ++ c[cpu][loop] = c0_count[cpu] = read_c0_count(); ++ mb(); ++ sync_cpus_slave(cpus++); ++ diff_count = c0_count[0] - c0_count[cpu]; ++ diff_count += prev_count; ++ diff_count += read_c0_count(); ++ write_c0_count(diff_count); ++ prev_count = (prev_count >> 1) + ++ ((int)(c0_count[0] - c0_count[cpu]) >> 1); ++ } ++ ++ /* Slave processor is done syncing count register with Master */ ++ sync_cpus_slave_exit(cpus++); ++ printk("SMP: Slave processor %d done syncing count \n", cpu); ++ local_irq_restore(flags); ++} ++ ++/* ++ * Master kicks off the syncing process ++ */ ++void sync_c0_count_master(void) ++{ ++ int cpus = 0, loop, cpu = smp_processor_id(); ++ unsigned long flags; ++ ++ printk("SMP: Starting to sync the c0 count register ... \n"); ++ sync_cpus_init(cpus++); ++ ++ /* Kick off the slave processors to also start the syncing process */ ++ smp_call_function(sync_c0_count_slave, NULL, 0, 0); ++ local_irq_save(flags); ++ ++ for (loop = 0; loop <= LOOPS; loop++) { ++ /* Wait for all the CPUs here */ ++ sync_cpus_master(cpus++); ++ c[cpu][loop] = c0_count[cpu] = read_c0_count(); ++ mb(); ++ /* Do syncing once more */ ++ sync_cpus_master(cpus++); ++ } ++ sync_cpus_master(cpus++); ++ local_irq_restore(flags); ++ ++ printk("SMP: Syncing process completed accross CPUs ... \n"); ++} ++#endif /* CONFIG_SMP */ + + static int null_rtc_set_time(unsigned long sec) + { +@@ -66,19 +215,30 @@ + int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; + int (*rtc_mips_set_mmss)(unsigned long); + +- + /* how many counter cycles in a jiffy */ + static unsigned long cycles_per_jiffy __read_mostly; + ++static unsigned long hrt_cycles_per_jiffy __read_mostly; ++ ++ + /* expirelo is the count value for next CPU timer interrupt */ + static unsigned int expirelo; + +- + /* + * Null timer ack for systems not needing one (e.g. i8254). + */ + static void null_timer_ack(void) { /* nothing */ } + ++#ifdef CONFIG_HIGH_RES_TIMERS ++/* ++ * Set the next event ++ */ ++static void mips_set_next_event(unsigned long evt) ++{ ++ write_c0_compare(read_c0_count() + evt); ++} ++#endif ++ + /* + * Null high precision timer functions for systems lacking one. + */ +@@ -95,13 +255,13 @@ + unsigned int count; + + /* Ack this timer interrupt and set the next one. */ +- expirelo += cycles_per_jiffy; ++ expirelo += hrt_cycles_per_jiffy; + write_c0_compare(expirelo); +- + /* Check to see if we have missed any timer interrupts. */ +- while (((count = read_c0_count()) - expirelo) < 0x7fffffff) { +- /* missed_timer_count++; */ +- expirelo = count + cycles_per_jiffy; ++ count = read_c0_count(); ++ if ((count - expirelo) < 0x7fffffff) { ++ /* missed_timer_count++; */ ++ expirelo = count + hrt_cycles_per_jiffy; + write_c0_compare(expirelo); + } + } +@@ -127,6 +287,29 @@ + /* last time when xtime and rtc are sync'ed up */ + static long last_rtc_update; + ++unsigned long read_persistent_clock(void) ++{ ++ unsigned long sec; ++ sec = rtc_mips_get_time(); ++ return sec; ++} ++ ++void sync_persistent_clock(struct timespec ts) ++{ ++ if (ntp_synced() && ++ xtime.tv_sec > last_rtc_update + 660 && ++ (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && ++ (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { ++ if (rtc_mips_set_mmss(xtime.tv_sec) == 0) { ++ last_rtc_update = xtime.tv_sec; ++ } ++ else { ++ /* do it again in 60 s */ ++ last_rtc_update = xtime.tv_sec - 600; ++ } ++ } ++} ++ + /* + * local_timer_interrupt() does profiling and process accounting + * on a per-CPU basis. +@@ -160,7 +343,7 @@ + + /* + * If we have an externally synchronized Linux clock, then update +- * CMOS clock accordingly every ~11 minutes. rtc_mips_set_time() has to be ++ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if (ntp_synced() && +@@ -228,6 +411,15 @@ + !r2; + } + ++#ifdef CONFIG_HIGH_RES_TIMERS ++void event_timer_handler(struct pt_regs *regs) ++{ ++ c0_timer_ack(); ++ if (lapic_clockevent.event_handler) ++ lapic_clockevent.event_handler(regs,NULL); ++} ++#endif ++ + asmlinkage void ll_timer_interrupt(int irq) + { + int r2 = cpu_has_mips_r2; +@@ -235,6 +427,16 @@ + irq_enter(); + kstat_this_cpu.irqs[irq]++; + ++ ++#ifdef CONFIG_HIGH_RES_TIMERS ++ /* ++ * Run the event handler ++ */ ++ if (!r2 || (read_c0_cause() & (1 << 26))) ++ if (lapic_clockevent.event_handler) ++ lapic_clockevent.event_handler(regs,NULL); ++#endif ++ + if (handle_perf_irq(r2)) + goto out; + +@@ -267,7 +469,7 @@ + * b) (optional) calibrate and set the mips_hpt_frequency + * (only needed if you intended to use cpu counter as timer interrupt + * source) +- * 2) setup xtime based on rtc_mips_get_time(). ++ * 2) setup xtime based on rtc_get_time(). + * 3) calculate a couple of cached variables for later usage + * 4) plat_timer_setup() - + * a) (optional) over-write any choices made above by time_init(). +@@ -281,7 +483,7 @@ + + static struct irqaction timer_irqaction = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_PERCPU, ++ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_NODELAY, + .name = "timer", + }; + +@@ -358,6 +560,9 @@ + + void __init time_init(void) + { ++#ifdef CONFIG_HIGH_RES_TIMERS ++ u64 temp; ++#endif + if (board_time_init) + board_time_init(); + +@@ -401,6 +606,12 @@ + if (!mips_hpt_frequency) + mips_hpt_frequency = calibrate_hpt(); + ++#ifdef CONFIG_HIGH_RES_TIMERS ++ hrt_cycles_per_jiffy = ( (CONFIG_CPU_SPEED * 1000000) + HZ / 2) / HZ; ++#else ++ hrt_cycles_per_jiffy = cycles_per_jiffy; ++#endif ++ + /* Report the high precision timer rate for a reference. */ + printk("Using %u.%03u MHz high precision timer.\n", + ((mips_hpt_frequency + 500) / 1000) / 1000, +diff -Nur custom-source-rt.orig/arch/mips/kernel/traps.c custom-source-rt/arch/mips/kernel/traps.c +--- custom-source-rt.orig/arch/mips/kernel/traps.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -309,7 +309,7 @@ + printk("\n"); + } + +-static DEFINE_SPINLOCK(die_lock); ++static DEFINE_RAW_SPINLOCK(die_lock); + + NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) + { +diff -Nur custom-source-rt.orig/arch/mips/mm/fault.c custom-source-rt/arch/mips/mm/fault.c +--- custom-source-rt.orig/arch/mips/mm/fault.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -68,7 +68,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (in_atomic() || !mm) ++ if (in_atomic() || !mm || current->pagefault_disabled) + goto bad_area_nosemaphore; + + down_read(&mm->mmap_sem); +diff -Nur custom-source-rt.orig/arch/mips/mm/highmem.c custom-source-rt/arch/mips/mm/highmem.c +--- custom-source-rt.orig/arch/mips/mm/highmem.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/mm/highmem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -38,7 +38,7 @@ + enum fixed_addresses idx; + unsigned long vaddr; + +- /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ ++ preempt_disable(); + pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); +@@ -63,6 +63,7 @@ + + if (vaddr < FIXADDR_START) { // FIXME + pagefault_enable(); ++ preempt_enable(); + return; + } + +@@ -78,6 +79,7 @@ + #endif + + pagefault_enable(); ++ preempt_enable(); + } + + /* +@@ -89,6 +91,7 @@ + enum fixed_addresses idx; + unsigned long vaddr; + ++ preempt_disable(); + pagefault_disable(); + + idx = type + KM_TYPE_NR*smp_processor_id(); +diff -Nur custom-source-rt.orig/arch/mips/mm/init.c custom-source-rt/arch/mips/mm/init.c +--- custom-source-rt.orig/arch/mips/mm/init.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -59,7 +59,7 @@ + + #endif /* CONFIG_MIPS_MT_SMTC */ + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + /* + * We have up to 8 empty zeroed pages so we can map one of the right colour +diff -Nur custom-source-rt.orig/arch/mips/sibyte/cfe/smp.c custom-source-rt/arch/mips/sibyte/cfe/smp.c +--- custom-source-rt.orig/arch/mips/sibyte/cfe/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/sibyte/cfe/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -107,4 +107,8 @@ + */ + void prom_cpus_done(void) + { ++#ifdef CONFIG_HIGH_RES_TIMERS ++ extern void sync_c0_count_master(void); ++ sync_c0_count_master(); ++#endif + } +diff -Nur custom-source-rt.orig/arch/mips/sibyte/sb1250/irq.c custom-source-rt/arch/mips/sibyte/sb1250/irq.c +--- custom-source-rt.orig/arch/mips/sibyte/sb1250/irq.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/sibyte/sb1250/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -81,7 +81,7 @@ + /* Store the CPU id (not the logical number) */ + int sb1250_irq_owner[SB1250_NR_IRQS]; + +-DEFINE_SPINLOCK(sb1250_imr_lock); ++DEFINE_RAW_SPINLOCK(sb1250_imr_lock); + + void sb1250_mask_irq(int cpu, int irq) + { +@@ -242,7 +242,7 @@ + + static struct irqaction sb1250_dummy_action = { + .handler = sb1250_dummy_handler, +- .flags = 0, ++ .flags = IRQF_NODELAY, + .mask = CPU_MASK_NONE, + .name = "sb1250-private", + .next = NULL, +@@ -352,6 +352,10 @@ + #ifdef CONFIG_KGDB + imask |= STATUSF_IP6; + #endif ++ ++#ifdef CONFIG_HIGH_RES_TIMERS ++ imask |= STATUSF_IP7; ++#endif + /* Enable necessary IPs, disable the rest */ + change_c0_status(ST0_IM, imask); + +@@ -429,6 +433,10 @@ + else + #endif + ++#ifdef CONFIG_HIGH_RES_TIMERS ++ if (pending & CAUSEF_IP7) ++ event_timer_handler(regs); ++#endif + if (pending & CAUSEF_IP4) + sb1250_timer_interrupt(); + +diff -Nur custom-source-rt.orig/arch/mips/sibyte/sb1250/smp.c custom-source-rt/arch/mips/sibyte/sb1250/smp.c +--- custom-source-rt.orig/arch/mips/sibyte/sb1250/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/sibyte/sb1250/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -59,7 +59,7 @@ + { + extern void sb1250_time_init(void); + sb1250_time_init(); +- local_irq_enable(); ++ raw_local_irq_enable(); + } + + /* +diff -Nur custom-source-rt.orig/arch/mips/sibyte/swarm/setup.c custom-source-rt/arch/mips/sibyte/swarm/setup.c +--- custom-source-rt.orig/arch/mips/sibyte/swarm/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/mips/sibyte/swarm/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -131,6 +131,12 @@ + rtc_mips_set_time = m41t81_set_time; + } + ++#ifdef CONFIG_HIGH_RES_TIMERS ++ /* ++ * set the mips_hpt_frequency here ++ */ ++ mips_hpt_frequency = CONFIG_CPU_SPEED * 1000000; ++#endif + printk("This kernel optimized for " + #ifdef CONFIG_SIMULATION + "simulation" +diff -Nur custom-source-rt.orig/arch/powerpc/Kconfig custom-source-rt/arch/powerpc/Kconfig +--- custom-source-rt.orig/arch/powerpc/Kconfig 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -31,18 +31,15 @@ + bool + default y + +-config GENERIC_HARDIRQS ++config GENERIC_TIME + bool + default y + +-config IRQ_PER_CPU ++config GENERIC_HARDIRQS + bool + default y + +-config RWSEM_GENERIC_SPINLOCK +- bool +- +-config RWSEM_XCHGADD_ALGORITHM ++config IRQ_PER_CPU + bool + default y + +@@ -347,7 +344,7 @@ + + config VIRT_CPU_ACCOUNTING + bool "Deterministic task and CPU time accounting" +- depends on PPC64 ++ depends on PPC64 && !GENERIC_CLOCKEVENTS + default y + help + Select this option to enable more accurate task and CPU time +@@ -406,7 +403,30 @@ + depends on PPC32 + + source kernel/Kconfig.hz ++ ++config GENERIC_CLOCKEVENTS ++ bool "Clock event devices support" ++ default n ++ help ++ Enable support for the clock event devices necessary for the ++ high-resolution timers and the tickless system support. ++ NOTE: This is not compatible with the deterministic time accounting ++ option on PPC64. ++ ++source kernel/time/Kconfig + source kernel/Kconfig.preempt ++ ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ default y ++ ++config ASM_SEMAPHORES ++ bool ++ default y ++ ++config RWSEM_XCHGADD_ALGORITHM ++ bool ++ + source "fs/Kconfig.binfmt" + + # We optimistically allocate largepages from the VM, so make the limit +diff -Nur custom-source-rt.orig/arch/powerpc/Kconfig.debug custom-source-rt/arch/powerpc/Kconfig.debug +--- custom-source-rt.orig/arch/powerpc/Kconfig.debug 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/Kconfig.debug 2007-10-02 17:31:08.000000000 +0000 +@@ -2,6 +2,10 @@ + + source "lib/Kconfig.debug" + ++config TRACE_IRQFLAGS_SUPPORT ++ bool ++ default y ++ + config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL +diff -Nur custom-source-rt.orig/arch/powerpc/boot/Makefile custom-source-rt/arch/powerpc/boot/Makefile +--- custom-source-rt.orig/arch/powerpc/boot/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/boot/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -31,6 +31,14 @@ + + BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) + ++ifdef CONFIG_MCOUNT ++# do not trace the boot loader ++nullstring := ++space := $(nullstring) # end of the line ++pg_flag = $(nullstring) -pg # end of the line ++CFLAGS := $(subst ${pg_flag},${space},${CFLAGS}) ++endif ++ + $(obj)/44x.o: BOOTCFLAGS += -mcpu=440 + $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 + +@@ -55,7 +63,7 @@ + obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) + + quiet_cmd_copy_zlib = COPY $@ +- cmd_copy_zlib = sed "s@__attribute_used__@@;s@]*\).*@\"\1\"@" $< > $@ ++ cmd_copy_zlib = sed "s@__attribute_used__@@;s@.include.@@;s@.include.@@;s@.*spin.*lock.*@@;s@.*SPINLOCK.*@@;s@]*\).*@\"\1\"@" $< > $@ + + quiet_cmd_copy_zlibheader = COPY $@ + cmd_copy_zlibheader = sed "s@]*\).*@\"\1\"@" $< > $@ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/Makefile custom-source-rt/arch/powerpc/kernel/Makefile +--- custom-source-rt.orig/arch/powerpc/kernel/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -10,10 +10,11 @@ + CFLAGS_btext.o += -fPIC + endif + +-obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ ++obj-y := cputable.o ptrace.o syscalls.o \ + irq.o align.o signal_32.o pmc.o vdso.o \ + init_task.o process.o systbl.o idle.o + obj-y += vdso32/ ++obj-$(CONFIG_ASM_SEMAPHORES) += semaphore.o + obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ + signal_64.o ptrace32.o \ + paca.o cpu_setup_ppc970.o \ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/asm-offsets.c custom-source-rt/arch/powerpc/kernel/asm-offsets.c +--- custom-source-rt.orig/arch/powerpc/kernel/asm-offsets.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/asm-offsets.c 2007-10-02 17:31:08.000000000 +0000 +@@ -273,16 +273,7 @@ + #endif /* ! CONFIG_PPC64 */ + + /* datapage offsets for use by vdso */ +- DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct vdso_data, tb_orig_stamp)); +- DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct vdso_data, tb_ticks_per_sec)); +- DEFINE(CFG_TB_TO_XS, offsetof(struct vdso_data, tb_to_xs)); +- DEFINE(CFG_STAMP_XSEC, offsetof(struct vdso_data, stamp_xsec)); +- DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct vdso_data, tb_update_count)); +- DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct vdso_data, tz_minuteswest)); +- DEFINE(CFG_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); + DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); +- DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); +- DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); + #ifdef CONFIG_PPC64 + DEFINE(CFG_SYSCALL_MAP64, offsetof(struct vdso_data, syscall_map_64)); + DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec)); +@@ -303,12 +294,6 @@ + DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); + DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); + +- /* Other bits used by the vdso */ +- DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); +- DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); +- DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); +- DEFINE(CLOCK_REALTIME_RES, TICK_NSEC); +- + #ifdef CONFIG_BUG + DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); + #endif +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/entry_32.S custom-source-rt/arch/powerpc/kernel/entry_32.S +--- custom-source-rt.orig/arch/powerpc/kernel/entry_32.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/entry_32.S 2007-10-02 17:31:08.000000000 +0000 +@@ -641,7 +641,7 @@ + /* Check current_thread_info()->flags */ + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_FLAGS(r9) +- andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) ++ andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne do_work + + restore_user: +@@ -863,7 +863,7 @@ + #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ + + do_work: /* r10 contains MSR_KERNEL here */ +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beq do_user_signal + + do_resched: /* r10 contains MSR_KERNEL here */ +@@ -877,7 +877,7 @@ + MTMSRD(r10) /* disable interrupts */ + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_FLAGS(r9) +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne- do_resched + andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK + beq restore_user +@@ -989,3 +989,85 @@ + /* XXX load up BATs and panic */ + + #endif /* CONFIG_PPC_RTAS */ ++ ++#ifdef CONFIG_MCOUNT ++/* ++ * mcount() is not the same as _mcount(). The callers of mcount() have a ++ * normal context. The callers of _mcount() do not have a stack frame and ++ * have not saved the "caller saves" registers. ++ */ ++_GLOBAL(mcount) ++ stwu r1,-16(r1) ++ mflr r3 ++ lis r5,mcount_enabled@ha ++ lwz r5,mcount_enabled@l(r5) ++ stw r3,20(r1) ++ cmpwi r5,0 ++ beq 1f ++ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ ++ lwz r4,16(r1) ++ lwz r4,4(r4) ++ bl __trace ++1: ++ lwz r0,20(r1) ++ mtlr r0 ++ addi r1,r1,16 ++ blr ++ ++/* ++ * The -pg flag, which is specified in the case of CONFIG_MCOUNT, causes the ++ * C compiler to add a call to _mcount() at the start of each function ++ * preamble, before the stack frame is created. An example of this preamble ++ * code is: ++ * ++ * mflr r0 ++ * lis r12,-16354 ++ * stw r0,4(r1) ++ * addi r0,r12,-19652 ++ * bl 0xc00034c8 <_mcount> ++ * mflr r0 ++ * stwu r1,-16(r1) ++ */ ++_GLOBAL(_mcount) ++#define M_STK_SIZE 48 ++ /* Would not expect to need to save cr, but glibc version of */ ++ /* _mcount() does, so cautiously saving it here too. */ ++ stwu r1,-M_STK_SIZE(r1) ++ stw r3, 12(r1) ++ stw r4, 16(r1) ++ stw r5, 20(r1) ++ stw r6, 24(r1) ++ mflr r3 /* will use as first arg to __trace() */ ++ mfcr r4 ++ lis r5,mcount_enabled@ha ++ lwz r5,mcount_enabled@l(r5) ++ cmpwi r5,0 ++ stw r3, 44(r1) /* lr */ ++ stw r4, 8(r1) /* cr */ ++ stw r7, 28(r1) ++ stw r8, 32(r1) ++ stw r9, 36(r1) ++ stw r10,40(r1) ++ beq 1f ++ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ ++ lwz r4,M_STK_SIZE+4(r1) ++ bl __trace ++1: ++ lwz r8, 8(r1) /* cr */ ++ lwz r9, 44(r1) /* lr */ ++ lwz r3, 12(r1) ++ lwz r4, 16(r1) ++ lwz r5, 20(r1) ++ mtcrf 0xff,r8 ++ mtctr r9 ++ lwz r0, 52(r1) ++ lwz r6, 24(r1) ++ lwz r7, 28(r1) ++ lwz r8, 32(r1) ++ lwz r9, 36(r1) ++ lwz r10,40(r1) ++ addi r1,r1,M_STK_SIZE ++ mtlr r0 ++ bctr ++ ++#endif /* CONFIG_MCOUNT */ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/entry_64.S custom-source-rt/arch/powerpc/kernel/entry_64.S +--- custom-source-rt.orig/arch/powerpc/kernel/entry_64.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/entry_64.S 2007-10-02 17:31:08.000000000 +0000 +@@ -449,7 +449,8 @@ + + #ifdef CONFIG_PREEMPT + clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ +- li r0,_TIF_NEED_RESCHED /* bits to check */ ++ li r0,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) ++ /* bits to check */ + ld r3,_MSR(r1) + ld r4,TI_FLAGS(r9) + /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */ +@@ -572,17 +573,22 @@ + rotldi r10,r10,16 + mtmsrd r10,1 + ld r4,TI_FLAGS(r9) +- andi. r0,r4,_TIF_NEED_RESCHED ++ andi. r0,r4,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne 1b + b restore + + user_work: + #endif ++ /* here we are preempting the current task */ ++ li r0,1 ++ stb r0,PACASOFTIRQEN(r13) ++ stb r0,PACAHARDIRQEN(r13) ++ + /* Enable interrupts */ + ori r10,r10,MSR_EE + mtmsrd r10,1 + +- andi. r0,r4,_TIF_NEED_RESCHED ++ andi. r0,r4,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beq 1f + bl .schedule + b .ret_from_except_lite +@@ -826,3 +832,63 @@ + ld r0,16(r1) + mtlr r0 + blr ++ ++#ifdef CONFIG_MCOUNT ++/* ++ * code almost taken from entry_32.S ++ */ ++#define MCOUNT_FRAME_SIZE 32 ++_GLOBAL(mcount) ++ stdu r1,-MCOUNT_FRAME_SIZE(r1) ++ mflr r3 ++ ++ LOAD_REG_ADDR(r5,mcount_enabled) ++ lwz r5,0(r5) ++ std r3,MCOUNT_FRAME_SIZE+16(r1) ++ cmpwi r5,0 ++ beq 1f ++ ++ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ ++ ld r4,MCOUNT_FRAME_SIZE(r1) ++ ld r4,16(r4) ++ bl .__trace ++ nop ++1: ++ ld r0,MCOUNT_FRAME_SIZE+16(r1) ++ mtlr r0 ++ addi r1,r1,MCOUNT_FRAME_SIZE ++ blr ++ ++/* ++ * Based on glibc-2.4/sysdeps/powerpc/powerpc64/ppc-mcount.S ++ * ++ * We don't need to save the parameter-passing registers as gcc takes ++ * care of that for us. Thus this function looks fairly normal. ++ * In fact, the generic code would work for us. ++ */ ++_GLOBAL(_mcount) ++ /* return if we're in real mode. */ ++ mfmsr r3 ++ andi. r0,r3,MSR_IR|MSR_DR /* see if relocation is on? */ ++ beqlr /* if not, do nothing. */ ++ /* we're in translation mode. keep going. */ ++ mflr r3 ++ ld r11,0(r1) /* load back chain ptr */ ++ stdu r1,-STACK_FRAME_OVERHEAD(r1) ++ std r3,STACK_FRAME_OVERHEAD+16(r1) ++ ld r4,16(r11) /* LR in back chain */ ++ LOAD_REG_ADDR(r5,mcount_enabled) ++ lwz r5,0(r5) ++ cmpwi r5,0 /* see if mcount_enabled? */ ++ beq 1f /* if disabled, then skip */ ++ ++ /* r3 contains lr (eip), put parent lr (parent_eip) in r4 */ ++ bl .__trace ++ nop ++1: ++ ld r0,STACK_FRAME_OVERHEAD+16(r1) /* restore saved LR */ ++ mtlr r0 ++ addi r1,r1,STACK_FRAME_OVERHEAD ++ blr ++ ++#endif /* CONFIG_MCOUNT */ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/head_64.S custom-source-rt/arch/powerpc/kernel/head_64.S +--- custom-source-rt.orig/arch/powerpc/kernel/head_64.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/head_64.S 2007-10-02 17:31:08.000000000 +0000 +@@ -1391,7 +1391,7 @@ + * handles any interrupts pending at this point. + */ + ld r3,SOFTE(r1) +- bl .local_irq_restore ++ bl .raw_local_irq_restore + b 11f + + /* Here we have a page fault that hash_page can't handle. */ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/idle.c custom-source-rt/arch/powerpc/kernel/idle.c +--- custom-source-rt.orig/arch/powerpc/kernel/idle.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/idle.c 2007-10-02 17:31:08.000000000 +0000 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -59,7 +60,9 @@ + + set_thread_flag(TIF_POLLING_NRFLAG); + while (1) { +- while (!need_resched() && !cpu_should_die()) { ++ tick_nohz_stop_sched_tick(); ++ while (!need_resched() && !need_resched_delayed() && ++ !cpu_should_die()) { + ppc64_runlatch_off(); + + if (ppc_md.power_save) { +@@ -72,7 +75,9 @@ + local_irq_disable(); + + /* check again after disabling irqs */ +- if (!need_resched() && !cpu_should_die()) ++ if (!need_resched() && ++ !need_resched_delayed() && ++ !cpu_should_die()) + ppc_md.power_save(); + + local_irq_enable(); +@@ -92,7 +97,10 @@ + ppc64_runlatch_on(); + if (cpu_should_die()) + cpu_die(); +- preempt_enable_no_resched(); ++ ++ tick_nohz_restart_sched_tick(); ++ ++ __preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/irq.c custom-source-rt/arch/powerpc/kernel/irq.c +--- custom-source-rt.orig/arch/powerpc/kernel/irq.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -94,8 +94,6 @@ + #endif + + #ifdef CONFIG_PPC64 +-EXPORT_SYMBOL(irq_desc); +- + int distribute_irqs = 1; + + static inline unsigned long get_hard_enabled(void) +@@ -114,7 +112,7 @@ + : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled))); + } + +-void local_irq_restore(unsigned long en) ++void notrace raw_local_irq_restore(unsigned long en) + { + /* + * get_paca()->soft_enabled = en; +@@ -405,7 +403,7 @@ + #ifdef CONFIG_PPC_MERGE + + static LIST_HEAD(irq_hosts); +-static DEFINE_SPINLOCK(irq_big_lock); ++static DEFINE_RAW_SPINLOCK(irq_big_lock); + static DEFINE_PER_CPU(unsigned int, irq_radix_reader); + static unsigned int irq_radix_writer; + struct irq_map_entry irq_map[NR_IRQS]; +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/pmc.c custom-source-rt/arch/powerpc/kernel/pmc.c +--- custom-source-rt.orig/arch/powerpc/kernel/pmc.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/pmc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -37,7 +37,7 @@ + } + + +-static DEFINE_SPINLOCK(pmc_owner_lock); ++static DEFINE_RAW_SPINLOCK(pmc_owner_lock); + static void *pmc_owner_caller; /* mostly for debugging */ + perf_irq_t perf_irq = dummy_perf; + +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/ppc_ksyms.c custom-source-rt/arch/powerpc/kernel/ppc_ksyms.c +--- custom-source-rt.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/ppc_ksyms.c 2007-10-02 17:31:08.000000000 +0000 +@@ -16,7 +16,6 @@ + #include + + #include +-#include + #include + #include + #include +@@ -50,7 +49,7 @@ + #endif + + #ifdef CONFIG_PPC64 +-EXPORT_SYMBOL(local_irq_restore); ++EXPORT_SYMBOL(raw_local_irq_restore); + #endif + + #ifdef CONFIG_PPC32 +@@ -177,7 +176,6 @@ + + #ifdef CONFIG_PPC32 + EXPORT_SYMBOL(timer_interrupt); +-EXPORT_SYMBOL(irq_desc); + EXPORT_SYMBOL(tb_ticks_per_jiffy); + EXPORT_SYMBOL(console_drivers); + EXPORT_SYMBOL(cacheable_memcpy); +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/rtas.c custom-source-rt/arch/powerpc/kernel/rtas.c +--- custom-source-rt.orig/arch/powerpc/kernel/rtas.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/rtas.c 2007-10-02 17:31:08.000000000 +0000 +@@ -36,7 +36,7 @@ + #include + + struct rtas_t rtas = { +- .lock = SPIN_LOCK_UNLOCKED ++ .lock = RAW_SPIN_LOCK_UNLOCKED(lock) + }; + EXPORT_SYMBOL(rtas); + +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/semaphore.c custom-source-rt/arch/powerpc/kernel/semaphore.c +--- custom-source-rt.orig/arch/powerpc/kernel/semaphore.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -31,7 +31,7 @@ + * sem->count = tmp; + * return old_count; + */ +-static inline int __sem_update_count(struct semaphore *sem, int incr) ++static inline int __sem_update_count(struct compat_semaphore *sem, int incr) + { + int old_count, tmp; + +@@ -50,7 +50,7 @@ + return old_count; + } + +-void __up(struct semaphore *sem) ++void __compat_up(struct compat_semaphore *sem) + { + /* + * Note that we incremented count in up() before we came here, +@@ -63,7 +63,7 @@ + __sem_update_count(sem, 1); + wake_up(&sem->wait); + } +-EXPORT_SYMBOL(__up); ++EXPORT_SYMBOL(__compat_up); + + /* + * Note that when we come in to __down or __down_interruptible, +@@ -73,7 +73,7 @@ + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. + */ +-void __sched __down(struct semaphore *sem) ++void __sched __compat_down(struct compat_semaphore *sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -101,9 +101,9 @@ + */ + wake_up(&sem->wait); + } +-EXPORT_SYMBOL(__down); ++EXPORT_SYMBOL(__compat_down); + +-int __sched __down_interruptible(struct semaphore * sem) ++int __sched __compat_down_interruptible(struct compat_semaphore *sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -132,4 +132,10 @@ + wake_up(&sem->wait); + return retval; + } +-EXPORT_SYMBOL(__down_interruptible); ++EXPORT_SYMBOL(__compat_down_interruptible); ++ ++int compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} ++EXPORT_SYMBOL(compat_sem_is_locked); +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/setup_64.c custom-source-rt/arch/powerpc/kernel/setup_64.c +--- custom-source-rt.orig/arch/powerpc/kernel/setup_64.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/setup_64.c 2007-10-02 17:31:08.000000000 +0000 +@@ -605,3 +605,22 @@ + EXPORT_SYMBOL(ppc_pci_io); + #endif /* CONFIG_PPC_INDIRECT_IO */ + ++#ifdef CONFIG_STACKTRACE ++#include ++void notrace save_stack_trace(struct stack_trace *trace, ++ struct task_struct *task) ++{ ++} ++#endif /* CONFIG_STACKTRACE */ ++ ++#ifdef CONFIG_EARLY_PRINTK ++void notrace early_printk(const char *fmt, ...) ++{ ++ BUG(); ++} ++#endif /* CONFIG_EARLY_PRINTK */ ++ ++#ifdef CONFIG_MCOUNT ++extern void _mcount(void); ++EXPORT_SYMBOL(_mcount); ++#endif /* CONFIG_MCOUNT */ +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/smp.c custom-source-rt/arch/powerpc/kernel/smp.c +--- custom-source-rt.orig/arch/powerpc/kernel/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -126,6 +126,16 @@ + smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); + } + ++/* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE); ++} ++ + #ifdef CONFIG_DEBUGGER + void smp_send_debugger_break(int cpu) + { +@@ -162,7 +172,7 @@ + * static memory requirements. It also looks cleaner. + * Stolen from the i386 version. + */ +-static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); ++static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(call_lock); + + static struct call_data_struct { + void (*func) (void *info); +@@ -331,8 +341,6 @@ + } + } + +-extern struct gettimeofday_struct do_gtod; +- + struct thread_info *current_set[NR_CPUS]; + + DECLARE_PER_CPU(unsigned int, pvr); +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/time.c custom-source-rt/arch/powerpc/kernel/time.c +--- custom-source-rt.orig/arch/powerpc/kernel/time.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -116,8 +117,6 @@ + u64 tb_to_ns_scale; + unsigned tb_to_ns_shift; + +-struct gettimeofday_struct do_gtod; +- + extern struct timezone sys_tz; + static long timezone_offset; + +@@ -127,6 +126,86 @@ + static u64 tb_last_jiffy __cacheline_aligned_in_smp; + static DEFINE_PER_CPU(u64, last_jiffy); + ++#ifdef CONFIG_GENERIC_CLOCKEVENTS ++ ++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) ++#define DECREMENTER_MAX 0xffffffff ++#else ++#define DECREMENTER_MAX 0x7fffffff /* setting MSB triggers an interrupt */ ++#endif ++ ++static int decrementer_set_next_event(unsigned long evt, ++ struct clock_event_device *dev) ++{ ++#if defined(CONFIG_40x) ++ mtspr(SPRN_PIT, evt); /* 40x has a hidden PIT auto-reload register */ ++#elif defined(CONFIG_BOOKE) ++ mtspr(SPRN_DECAR, evt); /* Book E has separate auto-reload register */ ++ set_dec(evt); ++#else ++ set_dec(evt - 1); /* Classic decrementer interrupts at -1 */ ++#endif ++ return 0; ++} ++ ++static void decrementer_set_mode(enum clock_event_mode mode, ++ struct clock_event_device *dev) ++{ ++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) ++ u32 tcr = mfspr(SPRN_TCR); ++ ++ tcr |= TCR_DIE; ++ switch (mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ tcr |= TCR_ARE; ++ break; ++ case CLOCK_EVT_MODE_ONESHOT: ++ tcr &= ~TCR_ARE; ++ break; ++ case CLOCK_EVT_MODE_UNUSED: ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ tcr &= ~TCR_DIE; ++ break; ++ case CLOCK_EVT_MODE_RESUME: ++ break; ++ } ++ mtspr(SPRN_TCR, tcr); ++ ++ if (mode == CLOCK_EVT_MODE_PERIODIC) ++ decrementer_set_next_event(tb_ticks_per_jiffy, dev); ++#endif ++} ++ ++static struct clock_event_device decrementer_clockevent = { ++ .name = "decrementer", ++#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) ++ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, ++#else ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++#endif ++ .shift = 32, ++ .rating = 200, ++ .irq = -1, ++ .set_next_event = decrementer_set_next_event, ++ .set_mode = decrementer_set_mode, ++}; ++ ++static DEFINE_PER_CPU(struct clock_event_device, decrementers); ++ ++static void register_decrementer(void) ++{ ++ int cpu = smp_processor_id(); ++ struct clock_event_device *decrementer = &per_cpu(decrementers, cpu); ++ ++ memcpy(decrementer, &decrementer_clockevent, sizeof(*decrementer)); ++ ++ decrementer->cpumask = cpumask_of_cpu(cpu); ++ ++ clockevents_register_device(decrementer); ++} ++ ++#endif /* CONFIG_GENERIC_CLOCKEVENTS */ ++ + #ifdef CONFIG_VIRT_CPU_ACCOUNTING + /* + * Factors for converting from cputime_t (timebase ticks) to +@@ -222,7 +301,7 @@ + int initialized; /* thread is running */ + u64 tb; /* last TB value read */ + u64 purr; /* last PURR value read */ +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data); +@@ -312,6 +391,9 @@ + { + __get_cpu_var(last_jiffy) = get_tb(); + snapshot_purr(); ++#ifdef CONFIG_GENERIC_CLOCKEVENTS ++ register_decrementer(); ++#endif + } + + void __delay(unsigned long loops) +@@ -375,162 +457,8 @@ + } + } + +-/* +- * This version of gettimeofday has microsecond resolution. +- */ +-static inline void __do_gettimeofday(struct timeval *tv) +-{ +- unsigned long sec, usec; +- u64 tb_ticks, xsec; +- struct gettimeofday_vars *temp_varp; +- u64 temp_tb_to_xs, temp_stamp_xsec; +- +- /* +- * These calculations are faster (gets rid of divides) +- * if done in units of 1/2^20 rather than microseconds. +- * The conversion to microseconds at the end is done +- * without a divide (and in fact, without a multiply) +- */ +- temp_varp = do_gtod.varp; +- +- /* Sampling the time base must be done after loading +- * do_gtod.varp in order to avoid racing with update_gtod. +- */ +- data_barrier(temp_varp); +- tb_ticks = get_tb() - temp_varp->tb_orig_stamp; +- temp_tb_to_xs = temp_varp->tb_to_xs; +- temp_stamp_xsec = temp_varp->stamp_xsec; +- xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs); +- sec = xsec / XSEC_PER_SEC; +- usec = (unsigned long)xsec & (XSEC_PER_SEC - 1); +- usec = SCALE_XSEC(usec, 1000000); +- +- tv->tv_sec = sec; +- tv->tv_usec = usec; +-} +- +-void do_gettimeofday(struct timeval *tv) +-{ +- if (__USE_RTC()) { +- /* do this the old way */ +- unsigned long flags, seq; +- unsigned int sec, nsec, usec; +- +- do { +- seq = read_seqbegin_irqsave(&xtime_lock, flags); +- sec = xtime.tv_sec; +- nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy); +- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); +- usec = nsec / 1000; +- while (usec >= 1000000) { +- usec -= 1000000; +- ++sec; +- } +- tv->tv_sec = sec; +- tv->tv_usec = usec; +- return; +- } +- __do_gettimeofday(tv); +-} +- +-EXPORT_SYMBOL(do_gettimeofday); +- +-/* +- * There are two copies of tb_to_xs and stamp_xsec so that no +- * lock is needed to access and use these values in +- * do_gettimeofday. We alternate the copies and as long as a +- * reasonable time elapses between changes, there will never +- * be inconsistent values. ntpd has a minimum of one minute +- * between updates. +- */ +-static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, +- u64 new_tb_to_xs) +-{ +- unsigned temp_idx; +- struct gettimeofday_vars *temp_varp; +- +- temp_idx = (do_gtod.var_idx == 0); +- temp_varp = &do_gtod.vars[temp_idx]; +- +- temp_varp->tb_to_xs = new_tb_to_xs; +- temp_varp->tb_orig_stamp = new_tb_stamp; +- temp_varp->stamp_xsec = new_stamp_xsec; +- smp_mb(); +- do_gtod.varp = temp_varp; +- do_gtod.var_idx = temp_idx; +- +- /* +- * tb_update_count is used to allow the userspace gettimeofday code +- * to assure itself that it sees a consistent view of the tb_to_xs and +- * stamp_xsec variables. It reads the tb_update_count, then reads +- * tb_to_xs and stamp_xsec and then reads tb_update_count again. If +- * the two values of tb_update_count match and are even then the +- * tb_to_xs and stamp_xsec values are consistent. If not, then it +- * loops back and reads them again until this criteria is met. +- * We expect the caller to have done the first increment of +- * vdso_data->tb_update_count already. +- */ +- vdso_data->tb_orig_stamp = new_tb_stamp; +- vdso_data->stamp_xsec = new_stamp_xsec; +- vdso_data->tb_to_xs = new_tb_to_xs; +- vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; +- vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; +- smp_wmb(); +- ++(vdso_data->tb_update_count); +-} +- +-/* +- * When the timebase - tb_orig_stamp gets too big, we do a manipulation +- * between tb_orig_stamp and stamp_xsec. The goal here is to keep the +- * difference tb - tb_orig_stamp small enough to always fit inside a +- * 32 bits number. This is a requirement of our fast 32 bits userland +- * implementation in the vdso. If we "miss" a call to this function +- * (interrupt latency, CPU locked in a spinlock, ...) and we end up +- * with a too big difference, then the vdso will fallback to calling +- * the syscall +- */ +-static __inline__ void timer_recalc_offset(u64 cur_tb) +-{ +- unsigned long offset; +- u64 new_stamp_xsec; +- u64 tlen, t2x; +- u64 tb, xsec_old, xsec_new; +- struct gettimeofday_vars *varp; +- +- if (__USE_RTC()) +- return; +- tlen = current_tick_length(); +- offset = cur_tb - do_gtod.varp->tb_orig_stamp; +- if (tlen == last_tick_len && offset < 0x80000000u) +- return; +- if (tlen != last_tick_len) { +- t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs); +- last_tick_len = tlen; +- } else +- t2x = do_gtod.varp->tb_to_xs; +- new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; +- do_div(new_stamp_xsec, 1000000000); +- new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; +- +- ++vdso_data->tb_update_count; +- smp_mb(); +- +- /* +- * Make sure time doesn't go backwards for userspace gettimeofday. +- */ +- tb = get_tb(); +- varp = do_gtod.varp; +- xsec_old = mulhdu(tb - varp->tb_orig_stamp, varp->tb_to_xs) +- + varp->stamp_xsec; +- xsec_new = mulhdu(tb - cur_tb, t2x) + new_stamp_xsec; +- if (xsec_new < xsec_old) +- new_stamp_xsec += xsec_old - xsec_new; +- +- update_gtod(cur_tb, new_stamp_xsec, t2x); +-} +- + #ifdef CONFIG_SMP +-unsigned long profile_pc(struct pt_regs *regs) ++unsigned long notrace profile_pc(struct pt_regs *regs) + { + unsigned long pc = instruction_pointer(regs); + +@@ -578,11 +506,7 @@ + tb_ticks_per_sec = new_tb_ticks_per_sec; + calc_cputime_factors(); + div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); +- do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; + tb_to_xs = divres.result_low; +- do_gtod.varp->tb_to_xs = tb_to_xs; +- vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; +- vdso_data->tb_to_xs = tb_to_xs; + } + else { + printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" +@@ -627,7 +551,27 @@ + old_regs = set_irq_regs(regs); + irq_enter(); + ++#ifdef CONFIG_GENERIC_CLOCKEVENTS ++#if !defined(CONFIG_40x) && !defined(CONFIG_BOOKE) ++ /* ++ * We must write a positive value to the decrementer to clear ++ * the interrupt on POWER4+ compatible CPUs. ++ */ ++ set_dec(DECREMENTER_MAX); ++#endif ++ /* ++ * We can't disable the decrementer, so in the period between ++ * CPU being marked offline and calling stop-self, it's taking ++ * timer interrupts... ++ */ ++ if (!cpu_is_offline(cpu)) { ++ struct clock_event_device *dev = &per_cpu(decrementers, cpu); ++ ++ dev->event_handler(dev); ++ } ++#else + profile_tick(CPU_PROFILING); ++#endif + calculate_steal_time(); + + #ifdef CONFIG_PPC_ISERIES +@@ -643,6 +587,7 @@ + if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000) + per_cpu(last_jiffy, cpu) -= 1000000000; + ++#ifndef CONFIG_GENERIC_CLOCKEVENTS + /* + * We cannot disable the decrementer, so in the period + * between this cpu's being marked offline in cpu_online_map +@@ -652,6 +597,7 @@ + */ + if (!cpu_is_offline(cpu)) + account_process_time(regs); ++#endif + + /* + * No need to check whether cpu is offline here; boot_cpuid +@@ -664,15 +610,19 @@ + tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; + if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { + tb_last_jiffy = tb_next_jiffy; ++#ifndef CONFIG_GENERIC_CLOCKEVENTS + do_timer(1); +- timer_recalc_offset(tb_last_jiffy); ++#endif ++ /*timer_recalc_offset(tb_last_jiffy);*/ + timer_check_rtc(); + } + write_sequnlock(&xtime_lock); + } +- ++ ++#ifndef CONFIG_GENERIC_CLOCKEVENTS + next_dec = tb_ticks_per_jiffy - ticks; + set_dec(next_dec); ++#endif + + #ifdef CONFIG_PPC_ISERIES + if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) +@@ -738,77 +688,6 @@ + return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift; + } + +-int do_settimeofday(struct timespec *tv) +-{ +- time_t wtm_sec, new_sec = tv->tv_sec; +- long wtm_nsec, new_nsec = tv->tv_nsec; +- unsigned long flags; +- u64 new_xsec; +- unsigned long tb_delta; +- +- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) +- return -EINVAL; +- +- write_seqlock_irqsave(&xtime_lock, flags); +- +- /* +- * Updating the RTC is not the job of this code. If the time is +- * stepped under NTP, the RTC will be updated after STA_UNSYNC +- * is cleared. Tools like clock/hwclock either copy the RTC +- * to the system time, in which case there is no point in writing +- * to the RTC again, or write to the RTC but then they don't call +- * settimeofday to perform this operation. +- */ +-#ifdef CONFIG_PPC_ISERIES +- if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) { +- iSeries_tb_recal(); +- first_settimeofday = 0; +- } +-#endif +- +- /* Make userspace gettimeofday spin until we're done. */ +- ++vdso_data->tb_update_count; +- smp_mb(); +- +- /* +- * Subtract off the number of nanoseconds since the +- * beginning of the last tick. +- */ +- tb_delta = tb_ticks_since(tb_last_jiffy); +- tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ +- new_nsec -= SCALE_XSEC(tb_delta, 1000000000); +- +- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec); +- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec); +- +- set_normalized_timespec(&xtime, new_sec, new_nsec); +- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); +- +- /* In case of a large backwards jump in time with NTP, we want the +- * clock to be updated as soon as the PLL is again in lock. +- */ +- last_rtc_update = new_sec - 658; +- +- ntp_clear(); +- +- new_xsec = xtime.tv_nsec; +- if (new_xsec != 0) { +- new_xsec *= XSEC_PER_SEC; +- do_div(new_xsec, NSEC_PER_SEC); +- } +- new_xsec += (u64)xtime.tv_sec * XSEC_PER_SEC; +- update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs); +- +- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; +- vdso_data->tz_dsttime = sys_tz.tz_dsttime; +- +- write_sequnlock_irqrestore(&xtime_lock, flags); +- clock_was_set(); +- return 0; +-} +- +-EXPORT_SYMBOL(do_settimeofday); +- + static int __init get_freq(char *name, int cells, unsigned long *val) + { + struct device_node *cpu; +@@ -864,31 +743,46 @@ + #endif + } + +-unsigned long get_boot_time(void) ++unsigned long read_persistent_clock(void) + { +- struct rtc_time tm; ++ unsigned long time = 0; ++ static int first = 1; ++ ++ if (first && ppc_md.time_init) { ++ timezone_offset = ppc_md.time_init(); ++ ++ /* If platform provided a timezone (pmac), we correct the time */ ++ if (timezone_offset) { ++ sys_tz.tz_minuteswest = -timezone_offset / 60; ++ sys_tz.tz_dsttime = 0; ++ } ++ } + + if (ppc_md.get_boot_time) +- return ppc_md.get_boot_time(); +- if (!ppc_md.get_rtc_time) +- return 0; +- ppc_md.get_rtc_time(&tm); +- return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, +- tm.tm_hour, tm.tm_min, tm.tm_sec); ++ time = ppc_md.get_boot_time(); ++ else if (ppc_md.get_rtc_time) { ++ struct rtc_time tm; ++ ++ ppc_md.get_rtc_time(&tm); ++ time = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec); ++ } ++ time -= timezone_offset; ++ ++ if (first) { ++ last_rtc_update = time; ++ first = 0; ++ } ++ return time; + } + + /* This function is only called on the boot processor */ + void __init time_init(void) + { +- unsigned long flags; +- unsigned long tm = 0; + struct div_result res; + u64 scale, x; + unsigned shift; + +- if (ppc_md.time_init != NULL) +- timezone_offset = ppc_md.time_init(); +- + if (__USE_RTC()) { + /* 601 processor: dec counts down by 128 every 128ns */ + ppc_tb_freq = 1000000000; +@@ -961,46 +855,21 @@ + tb_to_ns_scale = scale; + tb_to_ns_shift = shift; + +- tm = get_boot_time(); +- +- write_seqlock_irqsave(&xtime_lock, flags); +- +- /* If platform provided a timezone (pmac), we correct the time */ +- if (timezone_offset) { +- sys_tz.tz_minuteswest = -timezone_offset / 60; +- sys_tz.tz_dsttime = 0; +- tm -= timezone_offset; +- } +- +- xtime.tv_sec = tm; +- xtime.tv_nsec = 0; +- do_gtod.varp = &do_gtod.vars[0]; +- do_gtod.var_idx = 0; +- do_gtod.varp->tb_orig_stamp = tb_last_jiffy; +- __get_cpu_var(last_jiffy) = tb_last_jiffy; +- do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; +- do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; +- do_gtod.varp->tb_to_xs = tb_to_xs; +- do_gtod.tb_to_us = tb_to_us; +- +- vdso_data->tb_orig_stamp = tb_last_jiffy; +- vdso_data->tb_update_count = 0; +- vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; +- vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; +- vdso_data->tb_to_xs = tb_to_xs; +- +- time_freq = 0; +- +- last_rtc_update = xtime.tv_sec; +- set_normalized_timespec(&wall_to_monotonic, +- -xtime.tv_sec, -xtime.tv_nsec); +- write_sequnlock_irqrestore(&xtime_lock, flags); ++#ifdef CONFIG_GENERIC_CLOCKEVENTS ++ decrementer_clockevent.mult = div_sc(ppc_tb_freq, NSEC_PER_SEC, ++ decrementer_clockevent.shift); ++ decrementer_clockevent.max_delta_ns = ++ clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent); ++ decrementer_clockevent.min_delta_ns = ++ clockevent_delta2ns(0xf, &decrementer_clockevent); + ++ register_decrementer(); ++#else + /* Not exact, but the timer interrupt takes care of this */ + set_dec(tb_ticks_per_jiffy); ++#endif + } + +- + #define FEBRUARY 2 + #define STARTOFTIME 1970 + #define SECDAY 86400L +@@ -1145,3 +1014,39 @@ + dr->result_low = ((u64)y << 32) + z; + + } ++ ++/* PowerPC clocksource code */ ++ ++#include ++ ++static cycle_t notrace timebase_read(void) ++{ ++ return (cycle_t)get_tb(); ++} ++ ++struct clocksource clocksource_timebase = { ++ .name = "timebase", ++ .rating = 200, ++ .read = timebase_read, ++ .mask = (cycle_t)-1, ++ .mult = 0, ++ .shift = 22, ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++ ++/* XXX - this should be calculated or properly externed! */ ++static int __init init_timebase_clocksource(void) ++{ ++ if (__USE_RTC()) ++ return -ENODEV; ++ ++#ifdef CONFIG_PPC64 ++ clocksource_timebase.shift = tb_ticks_per_jiffy / 1000000; ++#endif ++ clocksource_timebase.mult = clocksource_hz2mult(tb_ticks_per_sec, ++ clocksource_timebase.shift); ++ return clocksource_register(&clocksource_timebase); ++} ++ ++module_init(init_timebase_clocksource); +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/traps.c custom-source-rt/arch/powerpc/kernel/traps.c +--- custom-source-rt.orig/arch/powerpc/kernel/traps.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -97,11 +97,11 @@ + int die(const char *str, struct pt_regs *regs, long err) + { + static struct { +- spinlock_t lock; ++ raw_spinlock_t lock; + u32 lock_owner; + int lock_owner_depth; + } die = { +- .lock = __SPIN_LOCK_UNLOCKED(die.lock), ++ .lock = _RAW_SPIN_LOCK_UNLOCKED(die.lock), + .lock_owner = -1, + .lock_owner_depth = 0 + }; +@@ -177,6 +177,11 @@ + return; + } + ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif ++ + memset(&info, 0, sizeof(info)); + info.si_signo = signr; + info.si_code = code; +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso32/Makefile custom-source-rt/arch/powerpc/kernel/vdso32/Makefile +--- custom-source-rt.orig/arch/powerpc/kernel/vdso32/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso32/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -1,7 +1,7 @@ + + # List of files in the vdso, has to be asm only for now + +-obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o ++obj-vdso32 = sigtramp.o datapage.o cacheflush.o note.o + + # Build rules + +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso32/datapage.S custom-source-rt/arch/powerpc/kernel/vdso32/datapage.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso32/datapage.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso32/datapage.S 2007-10-02 17:31:08.000000000 +0000 +@@ -65,21 +65,3 @@ + blr + .cfi_endproc + V_FUNCTION_END(__kernel_get_syscall_map) +- +-/* +- * void unsigned long long __kernel_get_tbfreq(void); +- * +- * returns the timebase frequency in HZ +- */ +-V_FUNCTION_BEGIN(__kernel_get_tbfreq) +- .cfi_startproc +- mflr r12 +- .cfi_register lr,r12 +- bl __get_datapage@local +- lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) +- lwz r3,CFG_TB_TICKS_PER_SEC(r3) +- mtlr r12 +- crclr cr0*4+so +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_get_tbfreq) +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso32/gettimeofday.S custom-source-rt/arch/powerpc/kernel/vdso32/gettimeofday.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso32/gettimeofday.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso32/gettimeofday.S 1970-01-01 00:00:00.000000000 +0000 +@@ -1,324 +0,0 @@ +-/* +- * Userland implementation of gettimeofday() for 32 bits processes in a +- * ppc64 kernel for use in the vDSO +- * +- * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org, +- * IBM Corp. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. +- */ +-#include +-#include +-#include +-#include +-#include +- +- .text +-/* +- * Exact prototype of gettimeofday +- * +- * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_gettimeofday) +- .cfi_startproc +- mflr r12 +- .cfi_register lr,r12 +- +- mr r10,r3 /* r10 saves tv */ +- mr r11,r4 /* r11 saves tz */ +- bl __get_datapage@local /* get data page */ +- mr r9, r3 /* datapage ptr in r9 */ +- cmplwi r10,0 /* check if tv is NULL */ +- beq 3f +- bl __do_get_xsec@local /* get xsec from tb & kernel */ +- bne- 2f /* out of line -> do syscall */ +- +- /* seconds are xsec >> 20 */ +- rlwinm r5,r4,12,20,31 +- rlwimi r5,r3,12,0,19 +- stw r5,TVAL32_TV_SEC(r10) +- +- /* get remaining xsec and convert to usec. we scale +- * up remaining xsec by 12 bits and get the top 32 bits +- * of the multiplication +- */ +- rlwinm r5,r4,12,0,19 +- lis r6,1000000@h +- ori r6,r6,1000000@l +- mulhwu r5,r5,r6 +- stw r5,TVAL32_TV_USEC(r10) +- +-3: cmplwi r11,0 /* check if tz is NULL */ +- beq 1f +- lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */ +- lwz r5,CFG_TZ_DSTTIME(r9) +- stw r4,TZONE_TZ_MINWEST(r11) +- stw r5,TZONE_TZ_DSTTIME(r11) +- +-1: mtlr r12 +- crclr cr0*4+so +- li r3,0 +- blr +- +-2: +- mtlr r12 +- mr r3,r10 +- mr r4,r11 +- li r0,__NR_gettimeofday +- sc +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_gettimeofday) +- +-/* +- * Exact prototype of clock_gettime() +- * +- * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_clock_gettime) +- .cfi_startproc +- /* Check for supported clock IDs */ +- cmpli cr0,r3,CLOCK_REALTIME +- cmpli cr1,r3,CLOCK_MONOTONIC +- cror cr0*4+eq,cr0*4+eq,cr1*4+eq +- bne cr0,99f +- +- mflr r12 /* r12 saves lr */ +- .cfi_register lr,r12 +- mr r10,r3 /* r10 saves id */ +- mr r11,r4 /* r11 saves tp */ +- bl __get_datapage@local /* get data page */ +- mr r9,r3 /* datapage ptr in r9 */ +- beq cr1,50f /* if monotonic -> jump there */ +- +- /* +- * CLOCK_REALTIME +- */ +- +- bl __do_get_xsec@local /* get xsec from tb & kernel */ +- bne- 98f /* out of line -> do syscall */ +- +- /* seconds are xsec >> 20 */ +- rlwinm r5,r4,12,20,31 +- rlwimi r5,r3,12,0,19 +- stw r5,TSPC32_TV_SEC(r11) +- +- /* get remaining xsec and convert to nsec. we scale +- * up remaining xsec by 12 bits and get the top 32 bits +- * of the multiplication, then we multiply by 1000 +- */ +- rlwinm r5,r4,12,0,19 +- lis r6,1000000@h +- ori r6,r6,1000000@l +- mulhwu r5,r5,r6 +- mulli r5,r5,1000 +- stw r5,TSPC32_TV_NSEC(r11) +- mtlr r12 +- crclr cr0*4+so +- li r3,0 +- blr +- +- /* +- * CLOCK_MONOTONIC +- */ +- +-50: bl __do_get_xsec@local /* get xsec from tb & kernel */ +- bne- 98f /* out of line -> do syscall */ +- +- /* seconds are xsec >> 20 */ +- rlwinm r6,r4,12,20,31 +- rlwimi r6,r3,12,0,19 +- +- /* get remaining xsec and convert to nsec. we scale +- * up remaining xsec by 12 bits and get the top 32 bits +- * of the multiplication, then we multiply by 1000 +- */ +- rlwinm r7,r4,12,0,19 +- lis r5,1000000@h +- ori r5,r5,1000000@l +- mulhwu r7,r7,r5 +- mulli r7,r7,1000 +- +- /* now we must fixup using wall to monotonic. We need to snapshot +- * that value and do the counter trick again. Fortunately, we still +- * have the counter value in r8 that was returned by __do_get_xsec. +- * At this point, r6,r7 contain our sec/nsec values, r3,r4 and r5 +- * can be used +- */ +- +- lwz r3,WTOM_CLOCK_SEC(r9) +- lwz r4,WTOM_CLOCK_NSEC(r9) +- +- /* We now have our result in r3,r4. We create a fake dependency +- * on that result and re-check the counter +- */ +- or r5,r4,r3 +- xor r0,r5,r5 +- add r9,r9,r0 +-#ifdef CONFIG_PPC64 +- lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) +-#else +- lwz r0,(CFG_TB_UPDATE_COUNT)(r9) +-#endif +- cmpl cr0,r8,r0 /* check if updated */ +- bne- 50b +- +- /* Calculate and store result. Note that this mimmics the C code, +- * which may cause funny results if nsec goes negative... is that +- * possible at all ? +- */ +- add r3,r3,r6 +- add r4,r4,r7 +- lis r5,NSEC_PER_SEC@h +- ori r5,r5,NSEC_PER_SEC@l +- cmpl cr0,r4,r5 +- cmpli cr1,r4,0 +- blt 1f +- subf r4,r5,r4 +- addi r3,r3,1 +-1: bge cr1,1f +- addi r3,r3,-1 +- add r4,r4,r5 +-1: stw r3,TSPC32_TV_SEC(r11) +- stw r4,TSPC32_TV_NSEC(r11) +- +- mtlr r12 +- crclr cr0*4+so +- li r3,0 +- blr +- +- /* +- * syscall fallback +- */ +-98: +- mtlr r12 +- mr r3,r10 +- mr r4,r11 +-99: +- li r0,__NR_clock_gettime +- sc +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_clock_gettime) +- +- +-/* +- * Exact prototype of clock_getres() +- * +- * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_clock_getres) +- .cfi_startproc +- /* Check for supported clock IDs */ +- cmpwi cr0,r3,CLOCK_REALTIME +- cmpwi cr1,r3,CLOCK_MONOTONIC +- cror cr0*4+eq,cr0*4+eq,cr1*4+eq +- bne cr0,99f +- +- li r3,0 +- cmpli cr0,r4,0 +- crclr cr0*4+so +- beqlr +- lis r5,CLOCK_REALTIME_RES@h +- ori r5,r5,CLOCK_REALTIME_RES@l +- stw r3,TSPC32_TV_SEC(r4) +- stw r5,TSPC32_TV_NSEC(r4) +- blr +- +- /* +- * syscall fallback +- */ +-99: +- li r0,__NR_clock_getres +- sc +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_clock_getres) +- +- +-/* +- * This is the core of gettimeofday() & friends, it returns the xsec +- * value in r3 & r4 and expects the datapage ptr (non clobbered) +- * in r9. clobbers r0,r4,r5,r6,r7,r8. +- * When returning, r8 contains the counter value that can be reused +- * by the monotonic clock implementation +- */ +-__do_get_xsec: +- .cfi_startproc +- /* Check for update count & load values. We use the low +- * order 32 bits of the update count +- */ +-#ifdef CONFIG_PPC64 +-1: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9) +-#else +-1: lwz r8,(CFG_TB_UPDATE_COUNT)(r9) +-#endif +- andi. r0,r8,1 /* pending update ? loop */ +- bne- 1b +- xor r0,r8,r8 /* create dependency */ +- add r9,r9,r0 +- +- /* Load orig stamp (offset to TB) */ +- lwz r5,CFG_TB_ORIG_STAMP(r9) +- lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) +- +- /* Get a stable TB value */ +-2: mftbu r3 +- mftbl r4 +- mftbu r0 +- cmpl cr0,r3,r0 +- bne- 2b +- +- /* Substract tb orig stamp. If the high part is non-zero, we jump to +- * the slow path which call the syscall. +- * If it's ok, then we have our 32 bits tb_ticks value in r7 +- */ +- subfc r7,r6,r4 +- subfe. r0,r5,r3 +- bne- 3f +- +- /* Load scale factor & do multiplication */ +- lwz r5,CFG_TB_TO_XS(r9) /* load values */ +- lwz r6,(CFG_TB_TO_XS+4)(r9) +- mulhwu r4,r7,r5 +- mulhwu r6,r7,r6 +- mullw r0,r7,r5 +- addc r6,r6,r0 +- +- /* At this point, we have the scaled xsec value in r4 + XER:CA +- * we load & add the stamp since epoch +- */ +- lwz r5,CFG_STAMP_XSEC(r9) +- lwz r6,(CFG_STAMP_XSEC+4)(r9) +- adde r4,r4,r6 +- addze r3,r5 +- +- /* We now have our result in r3,r4. We create a fake dependency +- * on that result and re-check the counter +- */ +- or r6,r4,r3 +- xor r0,r6,r6 +- add r9,r9,r0 +-#ifdef CONFIG_PPC64 +- lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) +-#else +- lwz r0,(CFG_TB_UPDATE_COUNT)(r9) +-#endif +- cmpl cr0,r8,r0 /* check if updated */ +- bne- 1b +- +- /* Warning ! The caller expects CR:EQ to be set to indicate a +- * successful calculation (so it won't fallback to the syscall +- * method). We have overriden that CR bit in the counter check, +- * but fortunately, the loop exit condition _is_ CR:EQ set, so +- * we can exit safely here. If you change this code, be careful +- * of that side effect. +- */ +-3: blr +- .cfi_endproc +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso32/vdso32.lds.S custom-source-rt/arch/powerpc/kernel/vdso32/vdso32.lds.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso32/vdso32.lds.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso32/vdso32.lds.S 2007-10-02 17:31:08.000000000 +0000 +@@ -117,10 +117,6 @@ + global: + __kernel_datapage_offset; /* Has to be there for the kernel to find */ + __kernel_get_syscall_map; +- __kernel_gettimeofday; +- __kernel_clock_gettime; +- __kernel_clock_getres; +- __kernel_get_tbfreq; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp32; +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso64/Makefile custom-source-rt/arch/powerpc/kernel/vdso64/Makefile +--- custom-source-rt.orig/arch/powerpc/kernel/vdso64/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso64/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -1,6 +1,6 @@ + # List of files in the vdso, has to be asm only for now + +-obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o ++obj-vdso64 = sigtramp.o datapage.o cacheflush.o note.o + + # Build rules + +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso64/datapage.S custom-source-rt/arch/powerpc/kernel/vdso64/datapage.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso64/datapage.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso64/datapage.S 2007-10-02 17:31:08.000000000 +0000 +@@ -65,21 +65,3 @@ + blr + .cfi_endproc + V_FUNCTION_END(__kernel_get_syscall_map) +- +- +-/* +- * void unsigned long __kernel_get_tbfreq(void); +- * +- * returns the timebase frequency in HZ +- */ +-V_FUNCTION_BEGIN(__kernel_get_tbfreq) +- .cfi_startproc +- mflr r12 +- .cfi_register lr,r12 +- bl V_LOCAL_FUNC(__get_datapage) +- ld r3,CFG_TB_TICKS_PER_SEC(r3) +- mtlr r12 +- crclr cr0*4+so +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_get_tbfreq) +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso64/gettimeofday.S custom-source-rt/arch/powerpc/kernel/vdso64/gettimeofday.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso64/gettimeofday.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso64/gettimeofday.S 1970-01-01 00:00:00.000000000 +0000 +@@ -1,255 +0,0 @@ +-/* +- * Userland implementation of gettimeofday() for 64 bits processes in a +- * ppc64 kernel for use in the vDSO +- * +- * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org), +- * IBM Corp. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. +- */ +-#include +-#include +-#include +-#include +-#include +- +- .text +-/* +- * Exact prototype of gettimeofday +- * +- * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_gettimeofday) +- .cfi_startproc +- mflr r12 +- .cfi_register lr,r12 +- +- mr r11,r3 /* r11 holds tv */ +- mr r10,r4 /* r10 holds tz */ +- bl V_LOCAL_FUNC(__get_datapage) /* get data page */ +- cmpldi r11,0 /* check if tv is NULL */ +- beq 2f +- bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ +- lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ +- ori r7,r7,16960 +- rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ +- rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ +- std r5,TVAL64_TV_SEC(r11) /* store sec in tv */ +- subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ +- mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / +- * XSEC_PER_SEC +- */ +- rldicl r0,r0,44,20 +- std r0,TVAL64_TV_USEC(r11) /* store usec in tv */ +-2: cmpldi r10,0 /* check if tz is NULL */ +- beq 1f +- lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ +- lwz r5,CFG_TZ_DSTTIME(r3) +- stw r4,TZONE_TZ_MINWEST(r10) +- stw r5,TZONE_TZ_DSTTIME(r10) +-1: mtlr r12 +- crclr cr0*4+so +- li r3,0 /* always success */ +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_gettimeofday) +- +- +-/* +- * Exact prototype of clock_gettime() +- * +- * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_clock_gettime) +- .cfi_startproc +- /* Check for supported clock IDs */ +- cmpwi cr0,r3,CLOCK_REALTIME +- cmpwi cr1,r3,CLOCK_MONOTONIC +- cror cr0*4+eq,cr0*4+eq,cr1*4+eq +- bne cr0,99f +- +- mflr r12 /* r12 saves lr */ +- .cfi_register lr,r12 +- mr r10,r3 /* r10 saves id */ +- mr r11,r4 /* r11 saves tp */ +- bl V_LOCAL_FUNC(__get_datapage) /* get data page */ +- beq cr1,50f /* if monotonic -> jump there */ +- +- /* +- * CLOCK_REALTIME +- */ +- +- bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ +- +- lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ +- ori r7,r7,16960 +- rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ +- rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ +- std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ +- subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ +- mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / +- * XSEC_PER_SEC +- */ +- rldicl r0,r0,44,20 +- mulli r0,r0,1000 /* nsec = usec * 1000 */ +- std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ +- +- mtlr r12 +- crclr cr0*4+so +- li r3,0 +- blr +- +- /* +- * CLOCK_MONOTONIC +- */ +- +-50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ +- +- lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ +- ori r7,r7,16960 +- rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ +- rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ +- subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ +- mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / +- * XSEC_PER_SEC +- */ +- rldicl r6,r0,44,20 +- mulli r6,r6,1000 /* nsec = usec * 1000 */ +- +- /* now we must fixup using wall to monotonic. We need to snapshot +- * that value and do the counter trick again. Fortunately, we still +- * have the counter value in r8 that was returned by __do_get_xsec. +- * At this point, r5,r6 contain our sec/nsec values. +- * can be used +- */ +- +- lwa r4,WTOM_CLOCK_SEC(r3) +- lwa r7,WTOM_CLOCK_NSEC(r3) +- +- /* We now have our result in r4,r7. We create a fake dependency +- * on that result and re-check the counter +- */ +- or r9,r4,r7 +- xor r0,r9,r9 +- add r3,r3,r0 +- ld r0,CFG_TB_UPDATE_COUNT(r3) +- cmpld cr0,r0,r8 /* check if updated */ +- bne- 50b +- +- /* Calculate and store result. Note that this mimmics the C code, +- * which may cause funny results if nsec goes negative... is that +- * possible at all ? +- */ +- add r4,r4,r5 +- add r7,r7,r6 +- lis r9,NSEC_PER_SEC@h +- ori r9,r9,NSEC_PER_SEC@l +- cmpl cr0,r7,r9 +- cmpli cr1,r7,0 +- blt 1f +- subf r7,r9,r7 +- addi r4,r4,1 +-1: bge cr1,1f +- addi r4,r4,-1 +- add r7,r7,r9 +-1: std r4,TSPC64_TV_SEC(r11) +- std r7,TSPC64_TV_NSEC(r11) +- +- mtlr r12 +- crclr cr0*4+so +- li r3,0 +- blr +- +- /* +- * syscall fallback +- */ +-98: +- mtlr r12 +- mr r3,r10 +- mr r4,r11 +-99: +- li r0,__NR_clock_gettime +- sc +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_clock_gettime) +- +- +-/* +- * Exact prototype of clock_getres() +- * +- * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); +- * +- */ +-V_FUNCTION_BEGIN(__kernel_clock_getres) +- .cfi_startproc +- /* Check for supported clock IDs */ +- cmpwi cr0,r3,CLOCK_REALTIME +- cmpwi cr1,r3,CLOCK_MONOTONIC +- cror cr0*4+eq,cr0*4+eq,cr1*4+eq +- bne cr0,99f +- +- li r3,0 +- cmpli cr0,r4,0 +- crclr cr0*4+so +- beqlr +- lis r5,CLOCK_REALTIME_RES@h +- ori r5,r5,CLOCK_REALTIME_RES@l +- std r3,TSPC64_TV_SEC(r4) +- std r5,TSPC64_TV_NSEC(r4) +- blr +- +- /* +- * syscall fallback +- */ +-99: +- li r0,__NR_clock_getres +- sc +- blr +- .cfi_endproc +-V_FUNCTION_END(__kernel_clock_getres) +- +- +-/* +- * This is the core of gettimeofday(), it returns the xsec +- * value in r4 and expects the datapage ptr (non clobbered) +- * in r3. clobbers r0,r4,r5,r6,r7,r8 +- * When returning, r8 contains the counter value that can be reused +- */ +-V_FUNCTION_BEGIN(__do_get_xsec) +- .cfi_startproc +- /* check for update count & load values */ +-1: ld r8,CFG_TB_UPDATE_COUNT(r3) +- andi. r0,r8,1 /* pending update ? loop */ +- bne- 1b +- xor r0,r8,r8 /* create dependency */ +- add r3,r3,r0 +- +- /* Get TB & offset it. We use the MFTB macro which will generate +- * workaround code for Cell. +- */ +- MFTB(r7) +- ld r9,CFG_TB_ORIG_STAMP(r3) +- subf r7,r9,r7 +- +- /* Scale result */ +- ld r5,CFG_TB_TO_XS(r3) +- mulhdu r7,r7,r5 +- +- /* Add stamp since epoch */ +- ld r6,CFG_STAMP_XSEC(r3) +- add r4,r6,r7 +- +- xor r0,r4,r4 +- add r3,r3,r0 +- ld r0,CFG_TB_UPDATE_COUNT(r3) +- cmpld cr0,r0,r8 /* check if updated */ +- bne- 1b +- blr +- .cfi_endproc +-V_FUNCTION_END(__do_get_xsec) +diff -Nur custom-source-rt.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S custom-source-rt/arch/powerpc/kernel/vdso64/vdso64.lds.S +--- custom-source-rt.orig/arch/powerpc/kernel/vdso64/vdso64.lds.S 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/kernel/vdso64/vdso64.lds.S 2007-10-02 17:31:08.000000000 +0000 +@@ -115,10 +115,6 @@ + global: + __kernel_datapage_offset; /* Has to be there for the kernel to find */ + __kernel_get_syscall_map; +- __kernel_gettimeofday; +- __kernel_clock_gettime; +- __kernel_clock_getres; +- __kernel_get_tbfreq; + __kernel_sync_dicache; + __kernel_sync_dicache_p5; + __kernel_sigtramp_rt64; +diff -Nur custom-source-rt.orig/arch/powerpc/lib/locks.c custom-source-rt/arch/powerpc/lib/locks.c +--- custom-source-rt.orig/arch/powerpc/lib/locks.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/lib/locks.c 2007-10-02 17:31:08.000000000 +0000 +@@ -25,7 +25,7 @@ + #include + #include + +-void __spin_yield(raw_spinlock_t *lock) ++void __spin_yield(__raw_spinlock_t *lock) + { + unsigned int lock_value, holder_cpu, yield_count; + +@@ -82,7 +82,7 @@ + } + #endif + +-void __raw_spin_unlock_wait(raw_spinlock_t *lock) ++void __raw_spin_unlock_wait(__raw_spinlock_t *lock) + { + while (lock->slock) { + HMT_low(); +diff -Nur custom-source-rt.orig/arch/powerpc/mm/fault.c custom-source-rt/arch/powerpc/mm/fault.c +--- custom-source-rt.orig/arch/powerpc/mm/fault.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -138,8 +138,8 @@ + * The return value is 0 if the fault was handled, or the signal + * number if this is a kernel fault that can't be handled here. + */ +-int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, +- unsigned long error_code) ++int __kprobes notrace do_page_fault(struct pt_regs *regs, ++ unsigned long address, unsigned long error_code) + { + struct vm_area_struct * vma; + struct mm_struct *mm = current->mm; +@@ -184,7 +184,7 @@ + } + #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ + +- if (in_atomic() || mm == NULL) { ++ if (in_atomic() || mm == NULL || current->pagefault_disabled) { + if (!user_mode(regs)) + return SIGSEGV; + /* in_atomic() in user mode is really bad, +diff -Nur custom-source-rt.orig/arch/powerpc/mm/hash_native_64.c custom-source-rt/arch/powerpc/mm/hash_native_64.c +--- custom-source-rt.orig/arch/powerpc/mm/hash_native_64.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/mm/hash_native_64.c 2007-10-02 17:31:08.000000000 +0000 +@@ -36,7 +36,7 @@ + + #define HPTE_LOCK_BIT 3 + +-static DEFINE_SPINLOCK(native_tlbie_lock); ++static DEFINE_RAW_SPINLOCK(native_tlbie_lock); + + static inline void __tlbie(unsigned long va, unsigned int psize) + { +diff -Nur custom-source-rt.orig/arch/powerpc/mm/init_32.c custom-source-rt/arch/powerpc/mm/init_32.c +--- custom-source-rt.orig/arch/powerpc/mm/init_32.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/mm/init_32.c 2007-10-02 17:31:08.000000000 +0000 +@@ -56,7 +56,7 @@ + #endif + #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + unsigned long total_memory; + unsigned long total_lowmem; +diff -Nur custom-source-rt.orig/arch/powerpc/mm/tlb_64.c custom-source-rt/arch/powerpc/mm/tlb_64.c +--- custom-source-rt.orig/arch/powerpc/mm/tlb_64.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/mm/tlb_64.c 2007-10-02 17:31:08.000000000 +0000 +@@ -31,13 +31,14 @@ + #include + #include + #include ++#include + + DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); + + /* This is declared as we are using the more or less generic + * include/asm-powerpc/tlb.h file -- tgall + */ +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); + unsigned long pte_freelist_forced_free; + +@@ -94,8 +95,11 @@ + + void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) + { +- /* This is safe since tlb_gather_mmu has disabled preemption */ +- cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); ++ /* ++ * This is safe since tlb_gather_mmu has disabled preemption. ++ * tlb->cpu is set by tlb_gather_mmu as well. ++ */ ++ cpumask_t local_cpumask = cpumask_of_cpu(tlb->cpu); + struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); + + if (atomic_read(&tlb->mm->mm_users) < 2 || +@@ -201,6 +205,18 @@ + batch->pte[i] = rpte; + batch->vaddr[i] = vaddr; + batch->index = ++i; ++ ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Since flushing tlb needs expensive hypervisor call(s) on celleb, ++ * always flush it on RT to reduce scheduling latency. ++ */ ++ if (machine_is(celleb)) { ++ flush_tlb_pending(); ++ return; ++ } ++#endif /* CONFIG_PREEMPT_RT */ ++ + if (i >= PPC64_TLB_BATCH_NR) + __flush_tlb_pending(batch); + } +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/cell/smp.c custom-source-rt/arch/powerpc/platforms/cell/smp.c +--- custom-source-rt.orig/arch/powerpc/platforms/cell/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/cell/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -133,7 +133,7 @@ + iic_setup_cpu(); + } + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned long timebase = 0; + + static void __devinit cell_give_timebase(void) +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/celleb/htab.c custom-source-rt/arch/powerpc/platforms/celleb/htab.c +--- custom-source-rt.orig/arch/powerpc/platforms/celleb/htab.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/celleb/htab.c 2007-10-02 17:31:08.000000000 +0000 +@@ -40,7 +40,7 @@ + #define DBG_LOW(fmt...) do { } while(0) + #endif + +-static DEFINE_SPINLOCK(beat_htab_lock); ++static DEFINE_RAW_SPINLOCK(beat_htab_lock); + + static inline unsigned int beat_read_mask(unsigned hpte_group) + { +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/celleb/interrupt.c custom-source-rt/arch/powerpc/platforms/celleb/interrupt.c +--- custom-source-rt.orig/arch/powerpc/platforms/celleb/interrupt.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/celleb/interrupt.c 2007-10-02 17:31:08.000000000 +0000 +@@ -29,8 +29,12 @@ + #include "interrupt.h" + #include "beat_wrapper.h" + ++#ifdef CONFIG_PREEMPT_HARDIRQS ++extern int hardirq_preemption; ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + #define MAX_IRQS NR_IRQS +-static DEFINE_SPINLOCK(beatic_irq_mask_lock); ++static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock); + static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; + static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64]; + +@@ -71,12 +75,35 @@ + spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + } + ++static void __beatic_eoi_irq(unsigned int irq_plug) ++{ ++ s64 err; ++ ++ if ((err = beat_downcount_of_interrupt(irq_plug)) != 0) { ++ if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ ++ panic("Failed to downcount IRQ! Error = %16lx", err); ++ ++ printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); ++ } ++} ++ + static void beatic_unmask_irq(unsigned int irq_plug) + { + unsigned long flags; + ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ __beatic_eoi_irq(irq_plug); ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + spin_lock_irqsave(&beatic_irq_mask_lock, flags); + beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); ++ ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ + beatic_update_irq_mask(irq_plug); + spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + } +@@ -93,15 +120,15 @@ + + static void beatic_end_irq(unsigned int irq_plug) + { +- s64 err; + unsigned long flags; + +- if ((err = beat_downcount_of_interrupt(irq_plug)) != 0) { +- if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ +- panic("Failed to downcount IRQ! Error = %16lx", err); ++#ifdef CONFIG_PREEMPT_HARDIRQS ++ if (hardirq_preemption) ++ return; ++#endif /* CONFIG_PREEMPT_HARDIRQS */ ++ ++ __beatic_eoi_irq(irq_plug); + +- printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); +- } + spin_lock_irqsave(&beatic_irq_mask_lock, flags); + beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); + beatic_update_irq_mask(irq_plug); +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/chrp/smp.c custom-source-rt/arch/powerpc/platforms/chrp/smp.c +--- custom-source-rt.orig/arch/powerpc/platforms/chrp/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/chrp/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -44,7 +44,7 @@ + mpic_setup_this_cpu(); + } + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned int timebase_upper = 0, timebase_lower = 0; + + void __devinit smp_chrp_give_timebase(void) +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/chrp/time.c custom-source-rt/arch/powerpc/platforms/chrp/time.c +--- custom-source-rt.orig/arch/powerpc/platforms/chrp/time.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/chrp/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -27,7 +27,7 @@ + #include + #include + +-extern spinlock_t rtc_lock; ++extern raw_spinlock_t rtc_lock; + + static int nvram_as1 = NVRAM_AS1; + static int nvram_as0 = NVRAM_AS0; +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/iseries/setup.c custom-source-rt/arch/powerpc/platforms/iseries/setup.c +--- custom-source-rt.orig/arch/powerpc/platforms/iseries/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/iseries/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -564,12 +564,14 @@ + static void iseries_shared_idle(void) + { + while (1) { +- while (!need_resched() && !hvlpevent_is_pending()) { ++ while (!need_resched() && !need_resched_delayed() ++ && !hvlpevent_is_pending()) { + local_irq_disable(); + ppc64_runlatch_off(); + + /* Recheck with irqs off */ +- if (!need_resched() && !hvlpevent_is_pending()) ++ if (!need_resched() && !need_resched_delayed() ++ && !hvlpevent_is_pending()) + yield_shared_processor(); + + HMT_medium(); +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/powermac/feature.c custom-source-rt/arch/powerpc/platforms/powermac/feature.c +--- custom-source-rt.orig/arch/powerpc/platforms/powermac/feature.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/powermac/feature.c 2007-10-02 17:31:08.000000000 +0000 +@@ -59,7 +59,7 @@ + * We use a single global lock to protect accesses. Each driver has + * to take care of its own locking + */ +-DEFINE_SPINLOCK(feature_lock); ++DEFINE_RAW_SPINLOCK(feature_lock); + + #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); + #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/powermac/nvram.c custom-source-rt/arch/powerpc/platforms/powermac/nvram.c +--- custom-source-rt.orig/arch/powerpc/platforms/powermac/nvram.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/powermac/nvram.c 2007-10-02 17:31:08.000000000 +0000 +@@ -80,7 +80,7 @@ + static int core99_bank = 0; + static int nvram_partitions[3]; + // XXX Turn that into a sem +-static DEFINE_SPINLOCK(nv_lock); ++static DEFINE_RAW_SPINLOCK(nv_lock); + + static int (*core99_write_bank)(int bank, u8* datas); + static int (*core99_erase_bank)(int bank); +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/powermac/pic.c custom-source-rt/arch/powerpc/platforms/powermac/pic.c +--- custom-source-rt.orig/arch/powerpc/platforms/powermac/pic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/powermac/pic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -63,7 +63,7 @@ + static int max_real_irqs; + static u32 level_mask[4]; + +-static DEFINE_SPINLOCK(pmac_pic_lock); ++static DEFINE_RAW_SPINLOCK(pmac_pic_lock); + + #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) + static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/pseries/setup.c custom-source-rt/arch/powerpc/platforms/pseries/setup.c +--- custom-source-rt.orig/arch/powerpc/platforms/pseries/setup.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/pseries/setup.c 2007-10-02 17:31:08.000000000 +0000 +@@ -412,7 +412,8 @@ + set_thread_flag(TIF_POLLING_NRFLAG); + + while (get_tb() < start_snooze) { +- if (need_resched() || cpu_is_offline(cpu)) ++ if (need_resched() || need_resched_delayed() || ++ cpu_is_offline(cpu)) + goto out; + ppc64_runlatch_off(); + HMT_low(); +@@ -423,7 +424,8 @@ + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb(); + local_irq_disable(); +- if (need_resched() || cpu_is_offline(cpu)) ++ if (need_resched() || need_resched_delayed() || ++ cpu_is_offline(cpu)) + goto out; + } + +diff -Nur custom-source-rt.orig/arch/powerpc/platforms/pseries/smp.c custom-source-rt/arch/powerpc/platforms/pseries/smp.c +--- custom-source-rt.orig/arch/powerpc/platforms/pseries/smp.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/platforms/pseries/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -154,7 +154,7 @@ + } + #endif /* CONFIG_XICS */ + +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned long timebase = 0; + + static void __devinit pSeries_give_timebase(void) +diff -Nur custom-source-rt.orig/arch/powerpc/sysdev/i8259.c custom-source-rt/arch/powerpc/sysdev/i8259.c +--- custom-source-rt.orig/arch/powerpc/sysdev/i8259.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/sysdev/i8259.c 2007-10-02 17:31:08.000000000 +0000 +@@ -23,7 +23,7 @@ + #define cached_A1 (cached_8259[0]) + #define cached_21 (cached_8259[1]) + +-static DEFINE_SPINLOCK(i8259_lock); ++static DEFINE_RAW_SPINLOCK(i8259_lock); + + static struct device_node *i8259_node; + static struct irq_host *i8259_host; +diff -Nur custom-source-rt.orig/arch/powerpc/sysdev/ipic.c custom-source-rt/arch/powerpc/sysdev/ipic.c +--- custom-source-rt.orig/arch/powerpc/sysdev/ipic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/sysdev/ipic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -30,7 +30,7 @@ + #include "ipic.h" + + static struct ipic * primary_ipic; +-static DEFINE_SPINLOCK(ipic_lock); ++static DEFINE_RAW_SPINLOCK(ipic_lock); + + static struct ipic_info ipic_info[] = { + [9] = { +diff -Nur custom-source-rt.orig/arch/powerpc/sysdev/mpic.c custom-source-rt/arch/powerpc/sysdev/mpic.c +--- custom-source-rt.orig/arch/powerpc/sysdev/mpic.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/sysdev/mpic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -46,7 +46,7 @@ + + static struct mpic *mpics; + static struct mpic *mpic_primary; +-static DEFINE_SPINLOCK(mpic_lock); ++static DEFINE_RAW_SPINLOCK(mpic_lock); + + #ifdef CONFIG_PPC32 /* XXX for now */ + #ifdef CONFIG_IRQ_ALL_CPUS +diff -Nur custom-source-rt.orig/arch/powerpc/xmon/xmon.c custom-source-rt/arch/powerpc/xmon/xmon.c +--- custom-source-rt.orig/arch/powerpc/xmon/xmon.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/powerpc/xmon/xmon.c 2007-10-02 17:31:08.000000000 +0000 +@@ -340,6 +340,7 @@ + unsigned long timeout; + #endif + ++ preempt_disable(); + local_irq_save(flags); + + bp = in_breakpoint_table(regs->nip, &offset); +@@ -516,6 +517,7 @@ + insert_cpu_bpts(); + + local_irq_restore(flags); ++ preempt_enable(); + + return cmd != 'X' && cmd != EOF; + } +@@ -2129,7 +2131,7 @@ + static unsigned long mdest; /* destination address */ + static unsigned long msrc; /* source address */ + static unsigned long mval; /* byte value to set memory to */ +-static unsigned long mcount; /* # bytes to affect */ ++static unsigned long xmon_mcount; /* # bytes to affect */ + static unsigned long mdiffs; /* max # differences to print */ + + void +@@ -2141,19 +2143,20 @@ + scanhex((void *)(cmd == 's'? &mval: &msrc)); + if( termch != '\n' ) + termch = 0; +- scanhex((void *)&mcount); ++ scanhex((void *)&xmon_mcount); + switch( cmd ){ + case 'm': +- memmove((void *)mdest, (void *)msrc, mcount); ++ memmove((void *)mdest, (void *)msrc, xmon_mcount); + break; + case 's': +- memset((void *)mdest, mval, mcount); ++ memset((void *)mdest, mval, xmon_mcount); + break; + case 'd': + if( termch != '\n' ) + termch = 0; + scanhex((void *)&mdiffs); +- memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); ++ memdiffs((unsigned char *)mdest, (unsigned char *)msrc, ++ xmon_mcount, mdiffs); + break; + } + } +diff -Nur custom-source-rt.orig/arch/ppc/8260_io/enet.c custom-source-rt/arch/ppc/8260_io/enet.c +--- custom-source-rt.orig/arch/ppc/8260_io/enet.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/8260_io/enet.c 2007-10-02 17:31:08.000000000 +0000 +@@ -115,7 +115,7 @@ + scc_t *sccp; + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static int scc_enet_open(struct net_device *dev); +diff -Nur custom-source-rt.orig/arch/ppc/8260_io/fcc_enet.c custom-source-rt/arch/ppc/8260_io/fcc_enet.c +--- custom-source-rt.orig/arch/ppc/8260_io/fcc_enet.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/8260_io/fcc_enet.c 2007-10-02 17:31:08.000000000 +0000 +@@ -375,7 +375,7 @@ + volatile fcc_enet_t *ep; + struct net_device_stats stats; + uint tx_free; +- spinlock_t lock; ++ raw_spinlock_t lock; + + #ifdef CONFIG_USE_MDIO + uint phy_id; +diff -Nur custom-source-rt.orig/arch/ppc/8xx_io/commproc.c custom-source-rt/arch/ppc/8xx_io/commproc.c +--- custom-source-rt.orig/arch/ppc/8xx_io/commproc.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/8xx_io/commproc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -370,7 +370,7 @@ + /* + * dpalloc / dpfree bits. + */ +-static spinlock_t cpm_dpmem_lock; ++static raw_spinlock_t cpm_dpmem_lock; + /* + * 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... +diff -Nur custom-source-rt.orig/arch/ppc/8xx_io/enet.c custom-source-rt/arch/ppc/8xx_io/enet.c +--- custom-source-rt.orig/arch/ppc/8xx_io/enet.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/8xx_io/enet.c 2007-10-02 17:31:08.000000000 +0000 +@@ -142,7 +142,7 @@ + unsigned char *rx_vaddr[RX_RING_SIZE]; + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + static int scc_enet_open(struct net_device *dev); +diff -Nur custom-source-rt.orig/arch/ppc/8xx_io/fec.c custom-source-rt/arch/ppc/8xx_io/fec.c +--- custom-source-rt.orig/arch/ppc/8xx_io/fec.c 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/8xx_io/fec.c 2007-10-02 17:31:08.000000000 +0000 +@@ -164,7 +164,7 @@ + + struct net_device_stats stats; + uint tx_full; +- spinlock_t lock; ++ raw_spinlock_t lock; + + #ifdef CONFIG_USE_MDIO + uint phy_id; +diff -Nur custom-source-rt.orig/arch/ppc/Kconfig custom-source-rt/arch/ppc/Kconfig +--- custom-source-rt.orig/arch/ppc/Kconfig 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -12,13 +12,6 @@ + bool + default y + +-config RWSEM_GENERIC_SPINLOCK +- bool +- +-config RWSEM_XCHGADD_ALGORITHM +- bool +- default y +- + config ARCH_HAS_ILOG2_U32 + bool + default y +@@ -988,6 +981,18 @@ + + source kernel/Kconfig.hz + source kernel/Kconfig.preempt ++ ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ default y ++ ++config ASM_SEMAPHORES ++ bool ++ default y ++ ++config RWSEM_XCHGADD_ALGORITHM ++ bool ++ + source "mm/Kconfig" + + source "fs/Kconfig.binfmt" +diff -Nur custom-source-rt.orig/arch/ppc/boot/Makefile custom-source-rt/arch/ppc/boot/Makefile +--- custom-source-rt.orig/arch/ppc/boot/Makefile 2007-08-21 04:00:17.000000000 +0000 ++++ custom-source-rt/arch/ppc/boot/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -14,6 +14,15 @@ + # + + CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include ++ ++ifdef CONFIG_MCOUNT ++# do not trace the boot loader ++nullstring := ++space := $(nullstring) # end of the line ++pg_flag = $(nullstring) -pg # end of the line ++CFLAGS := $(subst ${pg_flag},${space},${CFLAGS}) ++endif ++ + HOSTCFLAGS += -Iarch/$(ARCH)/boot/include + + BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd +diff -Nur custom-source-rt.orig/arch/ppc/kernel/entry.S custom-source-rt/arch/ppc/kernel/entry.S +--- custom-source-rt.orig/arch/ppc/kernel/entry.S 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/kernel/entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -863,7 +863,7 @@ + #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ + + do_work: /* r10 contains MSR_KERNEL here */ +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + beq do_user_signal + + do_resched: /* r10 contains MSR_KERNEL here */ +@@ -877,7 +877,7 @@ + MTMSRD(r10) /* disable interrupts */ + rlwinm r9,r1,0,0,18 + lwz r9,TI_FLAGS(r9) +- andi. r0,r9,_TIF_NEED_RESCHED ++ andi. r0,r9,(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED) + bne- do_resched + andi. r0,r9,_TIF_SIGPENDING + beq restore_user +diff -Nur custom-source-rt.orig/arch/ppc/kernel/semaphore.c custom-source-rt/arch/ppc/kernel/semaphore.c +--- custom-source-rt.orig/arch/ppc/kernel/semaphore.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -29,7 +29,7 @@ + * sem->count = tmp; + * return old_count; + */ +-static inline int __sem_update_count(struct semaphore *sem, int incr) ++static inline int __sem_update_count(struct compat_semaphore *sem, int incr) + { + int old_count, tmp; + +@@ -48,7 +48,7 @@ + return old_count; + } + +-void __up(struct semaphore *sem) ++void __compat_up(struct compat_semaphore *sem) + { + /* + * Note that we incremented count in up() before we came here, +@@ -70,7 +70,7 @@ + * Thus it is only when we decrement count from some value > 0 + * that we have actually got the semaphore. + */ +-void __sched __down(struct semaphore *sem) ++void __sched __compat_down(struct compat_semaphore *sem) + { + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); +@@ -100,7 +100,7 @@ + wake_up(&sem->wait); + } + +-int __sched __down_interruptible(struct semaphore * sem) ++int __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + int retval = 0; + struct task_struct *tsk = current; +@@ -129,3 +129,8 @@ + wake_up(&sem->wait); + return retval; + } ++ ++int compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} +diff -Nur custom-source-rt.orig/arch/ppc/kernel/smp.c custom-source-rt/arch/ppc/kernel/smp.c +--- custom-source-rt.orig/arch/ppc/kernel/smp.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -136,6 +136,16 @@ + smp_message_pass(cpu, PPC_MSG_RESCHEDULE); + } + ++/* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE, 0, 0); ++} ++ + #ifdef CONFIG_XMON + void smp_send_xmon_break(int cpu) + { +@@ -160,7 +170,7 @@ + * static memory requirements. It also looks cleaner. + * Stolen from the i386 version. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + static struct call_data_struct { + void (*func) (void *info); +diff -Nur custom-source-rt.orig/arch/ppc/kernel/time.c custom-source-rt/arch/ppc/kernel/time.c +--- custom-source-rt.orig/arch/ppc/kernel/time.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -102,7 +102,7 @@ + } + + #ifdef CONFIG_SMP +-unsigned long profile_pc(struct pt_regs *regs) ++unsigned long notrace profile_pc(struct pt_regs *regs) + { + unsigned long pc = instruction_pointer(regs); + +diff -Nur custom-source-rt.orig/arch/ppc/kernel/traps.c custom-source-rt/arch/ppc/kernel/traps.c +--- custom-source-rt.orig/arch/ppc/kernel/traps.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -72,7 +72,7 @@ + * Trap & Exception support + */ + +-DEFINE_SPINLOCK(die_lock); ++DEFINE_RAW_SPINLOCK(die_lock); + + int die(const char * str, struct pt_regs * fp, long err) + { +@@ -107,6 +107,10 @@ + debugger(regs); + die("Exception in kernel mode", regs, signr); + } ++#ifdef CONFIG_PREEMPT_RT ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + info.si_signo = signr; + info.si_errno = 0; + info.si_code = code; +diff -Nur custom-source-rt.orig/arch/ppc/lib/locks.c custom-source-rt/arch/ppc/lib/locks.c +--- custom-source-rt.orig/arch/ppc/lib/locks.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/lib/locks.c 2007-10-02 17:31:08.000000000 +0000 +@@ -42,7 +42,7 @@ + return ret; + } + +-void _raw_spin_lock(spinlock_t *lock) ++void __raw_spin_lock(raw_spinlock_t *lock) + { + int cpu = smp_processor_id(); + unsigned int stuck = INIT_STUCK; +@@ -62,9 +62,9 @@ + lock->owner_pc = (unsigned long)__builtin_return_address(0); + lock->owner_cpu = cpu; + } +-EXPORT_SYMBOL(_raw_spin_lock); ++EXPORT_SYMBOL(__raw_spin_lock); + +-int _raw_spin_trylock(spinlock_t *lock) ++int __raw_spin_trylock(raw_spinlock_t *lock) + { + if (__spin_trylock(&lock->lock)) + return 0; +@@ -72,9 +72,9 @@ + lock->owner_pc = (unsigned long)__builtin_return_address(0); + return 1; + } +-EXPORT_SYMBOL(_raw_spin_trylock); ++EXPORT_SYMBOL(__raw_spin_trylock); + +-void _raw_spin_unlock(spinlock_t *lp) ++void __raw_spin_unlock(raw_spinlock_t *lp) + { + if ( !lp->lock ) + printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", +@@ -88,13 +88,13 @@ + wmb(); + lp->lock = 0; + } +-EXPORT_SYMBOL(_raw_spin_unlock); ++EXPORT_SYMBOL(__raw_spin_unlock); + + /* + * For rwlocks, zero is unlocked, -1 is write-locked, + * positive is read-locked. + */ +-static __inline__ int __read_trylock(rwlock_t *rw) ++static __inline__ int __read_trylock(raw_rwlock_t *rw) + { + signed int tmp; + +@@ -114,13 +114,13 @@ + return tmp; + } + +-int _raw_read_trylock(rwlock_t *rw) ++int __raw_read_trylock(raw_rwlock_t *rw) + { + return __read_trylock(rw) > 0; + } +-EXPORT_SYMBOL(_raw_read_trylock); ++EXPORT_SYMBOL(__raw_read_trylock); + +-void _raw_read_lock(rwlock_t *rw) ++void __raw_read_lock(rwlock_t *rw) + { + unsigned int stuck; + +@@ -135,9 +135,9 @@ + } + } + } +-EXPORT_SYMBOL(_raw_read_lock); ++EXPORT_SYMBOL(__raw_read_lock); + +-void _raw_read_unlock(rwlock_t *rw) ++void __raw_read_unlock(raw_rwlock_t *rw) + { + if ( rw->lock == 0 ) + printk("_read_unlock(): %s/%d (nip %08lX) lock %d\n", +@@ -146,9 +146,9 @@ + wmb(); + atomic_dec((atomic_t *) &(rw)->lock); + } +-EXPORT_SYMBOL(_raw_read_unlock); ++EXPORT_SYMBOL(__raw_read_unlock); + +-void _raw_write_lock(rwlock_t *rw) ++void __raw_write_lock(raw_rwlock_t *rw) + { + unsigned int stuck; + +@@ -164,18 +164,18 @@ + } + wmb(); + } +-EXPORT_SYMBOL(_raw_write_lock); ++EXPORT_SYMBOL(__raw_write_lock); + +-int _raw_write_trylock(rwlock_t *rw) ++int __raw_write_trylock(raw_rwlock_t *rw) + { + if (cmpxchg(&rw->lock, 0, -1) != 0) + return 0; + wmb(); + return 1; + } +-EXPORT_SYMBOL(_raw_write_trylock); ++EXPORT_SYMBOL(__raw_write_trylock); + +-void _raw_write_unlock(rwlock_t *rw) ++void __raw_write_unlock(raw_rwlock_t *rw) + { + if (rw->lock >= 0) + printk("_write_lock(): %s/%d (nip %08lX) lock %d\n", +@@ -184,6 +184,6 @@ + wmb(); + rw->lock = 0; + } +-EXPORT_SYMBOL(_raw_write_unlock); ++EXPORT_SYMBOL(__raw_write_unlock); + + #endif +diff -Nur custom-source-rt.orig/arch/ppc/mm/fault.c custom-source-rt/arch/ppc/mm/fault.c +--- custom-source-rt.orig/arch/ppc/mm/fault.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -89,7 +89,7 @@ + * the error_code parameter is ESR for a data fault, 0 for an instruction + * fault. + */ +-int do_page_fault(struct pt_regs *regs, unsigned long address, ++int notrace do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) + { + struct vm_area_struct * vma; +diff -Nur custom-source-rt.orig/arch/ppc/mm/init.c custom-source-rt/arch/ppc/mm/init.c +--- custom-source-rt.orig/arch/ppc/mm/init.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -55,7 +55,7 @@ + #endif + #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + unsigned long total_memory; + unsigned long total_lowmem; +diff -Nur custom-source-rt.orig/arch/ppc/platforms/hdpu.c custom-source-rt/arch/ppc/platforms/hdpu.c +--- custom-source-rt.orig/arch/ppc/platforms/hdpu.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/platforms/hdpu.c 2007-10-02 17:31:08.000000000 +0000 +@@ -55,7 +55,7 @@ + static void hdpu_set_l1pe(void); + static void hdpu_cpustate_set(unsigned char new_state); + #ifdef CONFIG_SMP +-static DEFINE_SPINLOCK(timebase_lock); ++static DEFINE_RAW_SPINLOCK(timebase_lock); + static unsigned int timebase_upper = 0, timebase_lower = 0; + extern int smp_tb_synchronized; + +diff -Nur custom-source-rt.orig/arch/ppc/platforms/sbc82xx.c custom-source-rt/arch/ppc/platforms/sbc82xx.c +--- custom-source-rt.orig/arch/ppc/platforms/sbc82xx.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/platforms/sbc82xx.c 2007-10-02 17:31:08.000000000 +0000 +@@ -65,7 +65,7 @@ + + static volatile char *sbc82xx_i8259_map; + static char sbc82xx_i8259_mask = 0xff; +-static DEFINE_SPINLOCK(sbc82xx_i8259_lock); ++static DEFINE_RAW_SPINLOCK(sbc82xx_i8259_lock); + + static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr) + { +diff -Nur custom-source-rt.orig/arch/ppc/syslib/cpm2_common.c custom-source-rt/arch/ppc/syslib/cpm2_common.c +--- custom-source-rt.orig/arch/ppc/syslib/cpm2_common.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/syslib/cpm2_common.c 2007-10-02 17:31:08.000000000 +0000 +@@ -114,7 +114,7 @@ + /* + * dpalloc / dpfree bits. + */ +-static spinlock_t cpm_dpmem_lock; ++static raw_spinlock_t cpm_dpmem_lock; + /* 16 blocks should be enough to satisfy all requests + * until the memory subsystem goes up... */ + static rh_block_t cpm_boot_dpmem_rh_block[16]; +diff -Nur custom-source-rt.orig/arch/ppc/syslib/ocp.c custom-source-rt/arch/ppc/syslib/ocp.c +--- custom-source-rt.orig/arch/ppc/syslib/ocp.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/syslib/ocp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -44,11 +44,11 @@ + #include + #include + #include ++#include + + #include + #include + #include +-#include + #include + + //#define DBG(x) printk x +diff -Nur custom-source-rt.orig/arch/ppc/syslib/open_pic.c custom-source-rt/arch/ppc/syslib/open_pic.c +--- custom-source-rt.orig/arch/ppc/syslib/open_pic.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/syslib/open_pic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -526,7 +526,7 @@ + } + + #if defined(CONFIG_SMP) || defined(CONFIG_PM) +-static DEFINE_SPINLOCK(openpic_setup_lock); ++static DEFINE_RAW_SPINLOCK(openpic_setup_lock); + #endif + + #ifdef CONFIG_SMP +diff -Nur custom-source-rt.orig/arch/ppc/syslib/open_pic2.c custom-source-rt/arch/ppc/syslib/open_pic2.c +--- custom-source-rt.orig/arch/ppc/syslib/open_pic2.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/ppc/syslib/open_pic2.c 2007-10-02 17:31:08.000000000 +0000 +@@ -380,7 +380,7 @@ + vec); + } + +-static DEFINE_SPINLOCK(openpic2_setup_lock); ++static DEFINE_RAW_SPINLOCK(openpic2_setup_lock); + + /* + * Initialize a timer interrupt (and disable it) +diff -Nur custom-source-rt.orig/arch/sh/kernel/cpu/clock.c custom-source-rt/arch/sh/kernel/cpu/clock.c +--- custom-source-rt.orig/arch/sh/kernel/cpu/clock.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/cpu/clock.c 2007-10-02 17:31:08.000000000 +0000 +@@ -28,7 +28,7 @@ + #include + + static LIST_HEAD(clock_list); +-static DEFINE_SPINLOCK(clock_lock); ++static DEFINE_RAW_SPINLOCK(clock_lock); + static DEFINE_MUTEX(clock_list_sem); + + /* +diff -Nur custom-source-rt.orig/arch/sh/kernel/cpu/sh4/sq.c custom-source-rt/arch/sh/kernel/cpu/sh4/sq.c +--- custom-source-rt.orig/arch/sh/kernel/cpu/sh4/sq.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/cpu/sh4/sq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -37,7 +37,7 @@ + }; + + static struct sq_mapping *sq_mapping_list; +-static DEFINE_SPINLOCK(sq_mapping_lock); ++static DEFINE_RAW_SPINLOCK(sq_mapping_lock); + static struct kmem_cache *sq_cache; + static unsigned long *sq_bitmap; + +diff -Nur custom-source-rt.orig/arch/sh/kernel/entry-common.S custom-source-rt/arch/sh/kernel/entry-common.S +--- custom-source-rt.orig/arch/sh/kernel/entry-common.S 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/entry-common.S 2007-10-02 17:31:08.000000000 +0000 +@@ -157,7 +157,7 @@ + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt/s __restore_all +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED, r0 + + .align 2 + work_pending: +@@ -209,10 +209,10 @@ + tst #_TIF_WORK_MASK, r0 + bt __restore_all + bra work_pending +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_DELAYED, r0 + + .align 2 +-1: .long schedule ++1: .long __schedule + 2: .long do_notify_resume + 3: .long restore_all + #ifdef CONFIG_TRACE_IRQFLAGS +@@ -226,7 +226,7 @@ + ! r8: current_thread_info + tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0 + bt/s work_pending +- tst #_TIF_NEED_RESCHED, r0 ++ tst #_TIF_NEED_RESCHED| _TIF_NEED_RESCHED_DELAYED, r0 + #ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r0 + jsr @r0 +diff -Nur custom-source-rt.orig/arch/sh/kernel/irq.c custom-source-rt/arch/sh/kernel/irq.c +--- custom-source-rt.orig/arch/sh/kernel/irq.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -82,7 +82,7 @@ + static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; + #endif + +-asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) ++asmlinkage notrace int do_IRQ(unsigned int irq, struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); + #ifdef CONFIG_4KSTACKS +diff -Nur custom-source-rt.orig/arch/sh/kernel/process.c custom-source-rt/arch/sh/kernel/process.c +--- custom-source-rt.orig/arch/sh/kernel/process.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -62,7 +62,7 @@ + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + set_bl_bit(); +- while (!need_resched()) ++ while (!need_resched() && !need_resched_delayed()) + cpu_sleep(); + clear_bl_bit(); + set_thread_flag(TIF_POLLING_NRFLAG); +@@ -83,13 +83,15 @@ + idle = default_idle; + + tick_nohz_stop_sched_tick(); +- while (!need_resched()) ++ while (!need_resched() && !need_resched_delayed()) + idle(); + tick_nohz_restart_sched_tick(); + +- preempt_enable_no_resched(); +- schedule(); ++ local_irq_disable(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ local_irq_enable(); + check_pgt_cache(); + } + } +diff -Nur custom-source-rt.orig/arch/sh/kernel/semaphore.c custom-source-rt/arch/sh/kernel/semaphore.c +--- custom-source-rt.orig/arch/sh/kernel/semaphore.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/semaphore.c 2007-10-02 17:31:08.000000000 +0000 +@@ -46,7 +46,7 @@ + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +-void __up(struct semaphore *sem) ++void __attribute_used__ __compat_up(struct compat_semaphore *sem) + { + wake_one_more(sem); + wake_up(&sem->wait); +@@ -104,7 +104,7 @@ + tsk->state = TASK_RUNNING; \ + remove_wait_queue(&sem->wait, &wait); + +-void __sched __down(struct semaphore * sem) ++void __attribute_used__ __sched __compat_down(struct compat_semaphore * sem) + { + DOWN_VAR + DOWN_HEAD(TASK_UNINTERRUPTIBLE) +@@ -114,7 +114,7 @@ + DOWN_TAIL(TASK_UNINTERRUPTIBLE) + } + +-int __sched __down_interruptible(struct semaphore * sem) ++int __attribute_used__ __sched __compat_down_interruptible(struct compat_semaphore * sem) + { + int ret = 0; + DOWN_VAR +@@ -133,7 +133,13 @@ + return ret; + } + +-int __down_trylock(struct semaphore * sem) ++int __attribute_used__ __compat_down_trylock(struct compat_semaphore * sem) + { + return waking_non_zero_trylock(sem); + } ++ ++fastcall int __sched compat_sem_is_locked(struct compat_semaphore *sem) ++{ ++ return (int) atomic_read(&sem->count) < 0; ++} ++ +diff -Nur custom-source-rt.orig/arch/sh/kernel/sh_ksyms.c custom-source-rt/arch/sh/kernel/sh_ksyms.c +--- custom-source-rt.orig/arch/sh/kernel/sh_ksyms.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/sh_ksyms.c 2007-10-02 17:31:08.000000000 +0000 +@@ -26,7 +26,6 @@ + /* platform dependent support */ + EXPORT_SYMBOL(dump_fpu); + EXPORT_SYMBOL(kernel_thread); +-EXPORT_SYMBOL(irq_desc); + EXPORT_SYMBOL(no_irq_type); + + EXPORT_SYMBOL(strlen); +@@ -50,9 +49,9 @@ + #endif + + /* semaphore exports */ +-EXPORT_SYMBOL(__up); +-EXPORT_SYMBOL(__down); +-EXPORT_SYMBOL(__down_interruptible); ++EXPORT_SYMBOL(__compat_up); ++EXPORT_SYMBOL(__compat_down); ++EXPORT_SYMBOL(__compat_down_interruptible); + + EXPORT_SYMBOL(__udelay); + EXPORT_SYMBOL(__ndelay); +@@ -98,7 +97,7 @@ + EXPORT_SYMBOL(clear_user_page); + #endif + +-EXPORT_SYMBOL(__down_trylock); ++EXPORT_SYMBOL(__compat_down_trylock); + + #ifdef CONFIG_SMP + EXPORT_SYMBOL(synchronize_irq); +diff -Nur custom-source-rt.orig/arch/sh/kernel/signal.c custom-source-rt/arch/sh/kernel/signal.c +--- custom-source-rt.orig/arch/sh/kernel/signal.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -565,6 +565,13 @@ + struct k_sigaction ka; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ raw_local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +diff -Nur custom-source-rt.orig/arch/sh/kernel/time.c custom-source-rt/arch/sh/kernel/time.c +--- custom-source-rt.orig/arch/sh/kernel/time.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -24,7 +24,7 @@ + struct sys_timer *sys_timer; + + /* Move this somewhere more sensible.. */ +-DEFINE_SPINLOCK(rtc_lock); ++DEFINE_RAW_SPINLOCK(rtc_lock); + EXPORT_SYMBOL(rtc_lock); + + /* Dummy RTC ops */ +diff -Nur custom-source-rt.orig/arch/sh/kernel/timers/timer-tmu.c custom-source-rt/arch/sh/kernel/timers/timer-tmu.c +--- custom-source-rt.orig/arch/sh/kernel/timers/timer-tmu.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/timers/timer-tmu.c 2007-10-02 17:31:08.000000000 +0000 +@@ -80,6 +80,7 @@ + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: ++ case CLOCK_EVT_MODE_RESUME: + break; + } + } +diff -Nur custom-source-rt.orig/arch/sh/kernel/traps.c custom-source-rt/arch/sh/kernel/traps.c +--- custom-source-rt.orig/arch/sh/kernel/traps.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -77,7 +77,7 @@ + } + } + +-static DEFINE_SPINLOCK(die_lock); ++static DEFINE_RAW_SPINLOCK(die_lock); + + void die(const char * str, struct pt_regs * regs, long err) + { +diff -Nur custom-source-rt.orig/arch/sh/mm/cache-sh4.c custom-source-rt/arch/sh/mm/cache-sh4.c +--- custom-source-rt.orig/arch/sh/mm/cache-sh4.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/mm/cache-sh4.c 2007-10-02 17:31:08.000000000 +0000 +@@ -203,7 +203,7 @@ + index = CACHE_IC_ADDRESS_ARRAY | + (v & current_cpu_data.icache.entry_mask); + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + jump_to_P2(); + + for (i = 0; i < current_cpu_data.icache.ways; +@@ -212,7 +212,7 @@ + + back_to_P1(); + wmb(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + static inline void flush_cache_4096(unsigned long start, +@@ -228,10 +228,10 @@ + (start < CACHE_OC_ADDRESS_ARRAY)) + exec_offset = 0x20000000; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + __flush_cache_4096(start | SH_CACHE_ASSOC, + P1SEGADDR(phys), exec_offset); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + /* +@@ -259,7 +259,7 @@ + { + unsigned long flags, ccr; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + jump_to_P2(); + + /* Flush I-cache */ +@@ -273,7 +273,7 @@ + */ + + back_to_P1(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void flush_dcache_all(void) +diff -Nur custom-source-rt.orig/arch/sh/mm/init.c custom-source-rt/arch/sh/mm/init.c +--- custom-source-rt.orig/arch/sh/mm/init.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -20,7 +20,7 @@ + #include + #include + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + pgd_t swapper_pg_dir[PTRS_PER_PGD]; + + void (*copy_page)(void *from, void *to); +diff -Nur custom-source-rt.orig/arch/sh/mm/pg-sh4.c custom-source-rt/arch/sh/mm/pg-sh4.c +--- custom-source-rt.orig/arch/sh/mm/pg-sh4.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/mm/pg-sh4.c 2007-10-02 17:31:08.000000000 +0000 +@@ -39,9 +39,9 @@ + entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); + mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + set_pte(pte, entry); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + flush_tlb_one(get_asid(), p3_addr); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + update_mmu_cache(NULL, p3_addr, entry); + __clear_user_page((void *)p3_addr, to); + pte_clear(&init_mm, p3_addr, pte); +@@ -75,9 +75,9 @@ + entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); + mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); + set_pte(pte, entry); +- local_irq_save(flags); ++ raw_local_irq_save(flags); + flush_tlb_one(get_asid(), p3_addr); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + update_mmu_cache(NULL, p3_addr, entry); + __copy_user_page((void *)p3_addr, from, to); + pte_clear(&init_mm, p3_addr, pte); +diff -Nur custom-source-rt.orig/arch/sh/mm/tlb-flush.c custom-source-rt/arch/sh/mm/tlb-flush.c +--- custom-source-rt.orig/arch/sh/mm/tlb-flush.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/mm/tlb-flush.c 2007-10-02 17:31:08.000000000 +0000 +@@ -24,7 +24,7 @@ + asid = cpu_asid(cpu, vma->vm_mm); + page &= PAGE_MASK; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + if (vma->vm_mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); +@@ -32,7 +32,7 @@ + local_flush_tlb_one(asid, page); + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -46,7 +46,7 @@ + unsigned long flags; + int size; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + cpu_context(cpu, mm) = NO_CONTEXT; +@@ -71,7 +71,7 @@ + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); + } +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -81,7 +81,7 @@ + unsigned long flags; + int size; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + local_flush_tlb_all(); +@@ -100,7 +100,7 @@ + } + set_asid(saved_asid); + } +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void local_flush_tlb_mm(struct mm_struct *mm) +@@ -112,11 +112,11 @@ + if (cpu_context(cpu, mm) != NO_CONTEXT) { + unsigned long flags; + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + cpu_context(cpu, mm) = NO_CONTEXT; + if (mm == current->mm) + activate_context(mm, cpu); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + } + +@@ -131,10 +131,10 @@ + * TF-bit for SH-3, TI-bit for SH-4. + * It's same position, bit #2. + */ +- local_irq_save(flags); ++ raw_local_irq_save(flags); + status = ctrl_inl(MMUCR); + status |= 0x04; + ctrl_outl(status, MMUCR); + ctrl_barrier(); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } +diff -Nur custom-source-rt.orig/arch/sh/mm/tlb-sh4.c custom-source-rt/arch/sh/mm/tlb-sh4.c +--- custom-source-rt.orig/arch/sh/mm/tlb-sh4.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sh/mm/tlb-sh4.c 2007-10-02 17:31:08.000000000 +0000 +@@ -51,7 +51,7 @@ + } + } + +- local_irq_save(flags); ++ raw_local_irq_save(flags); + + /* Set PTEH register */ + vpn = (address & MMU_VPN_MASK) | get_asid(); +@@ -74,7 +74,7 @@ + + /* Load the TLB */ + asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); +- local_irq_restore(flags); ++ raw_local_irq_restore(flags); + } + + void local_flush_tlb_one(unsigned long asid, unsigned long page) +diff -Nur custom-source-rt.orig/arch/sparc/kernel/smp.c custom-source-rt/arch/sparc/kernel/smp.c +--- custom-source-rt.orig/arch/sparc/kernel/smp.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sparc/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -68,16 +68,6 @@ + cpu_data(id).prom_node = cpu_node; + cpu_data(id).mid = cpu_get_hwmid(cpu_node); + +- /* this is required to tune the scheduler correctly */ +- /* is it possible to have CPUs with different cache sizes? */ +- if (id == boot_cpu_id) { +- int cache_line,cache_nlines; +- cache_line = 0x20; +- cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line); +- cache_nlines = 0x8000; +- cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines); +- max_cache_size = cache_line * cache_nlines; +- } + if (cpu_data(id).mid < 0) + panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); + } +diff -Nur custom-source-rt.orig/arch/sparc/mm/highmem.c custom-source-rt/arch/sparc/mm/highmem.c +--- custom-source-rt.orig/arch/sparc/mm/highmem.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sparc/mm/highmem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -34,7 +34,7 @@ + unsigned long idx; + unsigned long vaddr; + +- /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ ++ preempt_disable(); + pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); +@@ -71,6 +71,7 @@ + + if (vaddr < FIXADDR_START) { // FIXME + pagefault_enable(); ++ preempt_enable(); + return; + } + +@@ -97,6 +98,7 @@ + #endif + + pagefault_enable(); ++ preempt_enable(); + } + + /* We may be fed a pagetable here by ptep_to_xxx and others. */ +diff -Nur custom-source-rt.orig/arch/sparc64/Kconfig custom-source-rt/arch/sparc64/Kconfig +--- custom-source-rt.orig/arch/sparc64/Kconfig 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sparc64/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -23,6 +23,10 @@ + bool + default y + ++config GENERIC_CMOS_UPDATE ++ bool ++ default y ++ + config GENERIC_CLOCKEVENTS + bool + default y +diff -Nur custom-source-rt.orig/arch/sparc64/kernel/smp.c custom-source-rt/arch/sparc64/kernel/smp.c +--- custom-source-rt.orig/arch/sparc64/kernel/smp.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sparc64/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1228,35 +1228,8 @@ + return -EINVAL; + } + +-static void __init smp_tune_scheduling(void) +-{ +- unsigned int smallest = ~0U; +- int i; +- +- for (i = 0; i < NR_CPUS; i++) { +- unsigned int val = cpu_data(i).ecache_size; +- +- if (val && val < smallest) +- smallest = val; +- } +- +- /* Any value less than 256K is nonsense. */ +- if (smallest < (256U * 1024U)) +- smallest = 256 * 1024; +- +- max_cache_size = smallest; +- +- if (smallest < 1U * 1024U * 1024U) +- printk(KERN_INFO "Using max_cache_size of %uKB\n", +- smallest / 1024U); +- else +- printk(KERN_INFO "Using max_cache_size of %uMB\n", +- smallest / 1024U / 1024U); +-} +- + void __init smp_prepare_cpus(unsigned int max_cpus) + { +- smp_tune_scheduling(); + } + + void __devinit smp_prepare_boot_cpu(void) +diff -Nur custom-source-rt.orig/arch/sparc64/kernel/time.c custom-source-rt/arch/sparc64/kernel/time.c +--- custom-source-rt.orig/arch/sparc64/kernel/time.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/sparc64/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -403,58 +403,9 @@ + + static unsigned long timer_ticks_per_nsec_quotient __read_mostly; + +-#define TICK_SIZE (tick_nsec / 1000) +- +-#define USEC_AFTER 500000 +-#define USEC_BEFORE 500000 +- +-static void sync_cmos_clock(unsigned long dummy); +- +-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); +- +-static void sync_cmos_clock(unsigned long dummy) +-{ +- struct timeval now, next; +- int fail = 1; +- +- /* +- * If we have an externally synchronized Linux clock, then update +- * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be +- * called as close as possible to 500 ms before the new second starts. +- * This code is run on a timer. If the clock is set, that timer +- * may not expire at the correct time. Thus, we adjust... +- */ +- if (!ntp_synced()) +- /* +- * Not synced, exit, do not restart a timer (if one is +- * running, let it run out). +- */ +- return; +- +- do_gettimeofday(&now); +- if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 && +- now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) +- fail = set_rtc_mmss(now.tv_sec); +- +- next.tv_usec = USEC_AFTER - now.tv_usec; +- if (next.tv_usec <= 0) +- next.tv_usec += USEC_PER_SEC; +- +- if (!fail) +- next.tv_sec = 659; +- else +- next.tv_sec = 0; +- +- if (next.tv_usec >= USEC_PER_SEC) { +- next.tv_sec++; +- next.tv_usec -= USEC_PER_SEC; +- } +- mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next)); +-} +- +-void notify_arch_cmos_timer(void) ++int update_persistent_clock(struct timespec now) + { +- mod_timer(&sync_cmos_timer, jiffies + 1); ++ return set_rtc_mmss(now.tv_sec); + } + + /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ +@@ -931,6 +882,7 @@ + { + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: ++ case CLOCK_EVT_MODE_RESUME: + break; + + case CLOCK_EVT_MODE_SHUTDOWN: +diff -Nur custom-source-rt.orig/arch/x86_64/Kconfig custom-source-rt/arch/x86_64/Kconfig +--- custom-source-rt.orig/arch/x86_64/Kconfig 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -28,10 +28,26 @@ + bool + default y + ++config GENERIC_CLOCKEVENTS ++ bool ++ default y ++ ++config GENERIC_CLOCKEVENTS_BROADCAST ++ bool ++ default y ++ ++config NONIRQ_WAKEUP ++ bool ++ default y ++ + config GENERIC_TIME_VSYSCALL + bool + default y + ++config GENERIC_CMOS_UPDATE ++ bool ++ default y ++ + config ZONE_DMA32 + bool + default y +@@ -62,13 +78,6 @@ + config SBUS + bool + +-config RWSEM_GENERIC_SPINLOCK +- bool +- default y +- +-config RWSEM_XCHGADD_ALGORITHM +- bool +- + config GENERIC_HWEIGHT + bool + default y +@@ -126,6 +135,8 @@ + + menu "Processor type and features" + ++source "kernel/time/Kconfig" ++ + choice + prompt "Subarchitecture Type" + default X86_PC +@@ -343,6 +354,14 @@ + If the system is EM64T, you should say N unless your system is EM64T + NUMA. + ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ default y ++ ++config RWSEM_XCHGADD_ALGORITHM ++ depends on !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT ++ bool ++ + config K8_NUMA + bool "Old style AMD Opteron NUMA detection" + depends on NUMA && PCI +@@ -698,6 +717,8 @@ + + source "arch/x86_64/kernel/cpufreq/Kconfig" + ++source "drivers/cpuidle/Kconfig" ++ + endmenu + + menu "Bus options (PCI etc.)" +diff -Nur custom-source-rt.orig/arch/x86_64/ia32/ia32entry.S custom-source-rt/arch/x86_64/ia32/ia32entry.S +--- custom-source-rt.orig/arch/x86_64/ia32/ia32entry.S 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/arch/x86_64/ia32/ia32entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -132,7 +132,9 @@ + cmpl $(IA32_NR_syscalls-1),%eax + ja ia32_badsys + IA32_ARG_FIXUP 1 ++ TRACE_SYS_IA32_CALL + call *ia32_sys_call_table(,%rax,8) ++ TRACE_SYS_RET + movq %rax,RAX-ARGOFFSET(%rsp) + GET_THREAD_INFO(%r10) + cli +@@ -241,7 +243,9 @@ + cmpl $IA32_NR_syscalls-1,%eax + ja ia32_badsys + IA32_ARG_FIXUP 1 ++ TRACE_SYS_IA32_CALL + call *ia32_sys_call_table(,%rax,8) ++ TRACE_SYS_RET + movq %rax,RAX-ARGOFFSET(%rsp) + GET_THREAD_INFO(%r10) + cli +@@ -335,8 +339,10 @@ + cmpl $(IA32_NR_syscalls-1),%eax + ja ia32_badsys + IA32_ARG_FIXUP ++ TRACE_SYS_IA32_CALL + call *ia32_sys_call_table(,%rax,8) # xxx: rip relative + ia32_sysret: ++ TRACE_SYS_RET + movq %rax,RAX-ARGOFFSET(%rsp) + jmp int_ret_from_sys_call + +@@ -406,7 +412,7 @@ + + .section .rodata,"a" + .align 8 +-ia32_sys_call_table: ++ENTRY(ia32_sys_call_table) + .quad sys_restart_syscall + .quad sys_exit + .quad stub32_fork +@@ -731,4 +737,7 @@ + .quad compat_sys_signalfd + .quad compat_sys_timerfd + .quad sys_eventfd ++#ifdef CONFIG_EVENT_TRACE ++ .globl ia32_syscall_end ++#endif + ia32_syscall_end: +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/Makefile custom-source-rt/arch/x86_64/kernel/Makefile +--- custom-source-rt.orig/arch/x86_64/kernel/Makefile 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -9,7 +9,7 @@ + x8664_ksyms.o i387.o syscall.o vsyscall.o \ + setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ + pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o \ +- perfctr-watchdog.o ++ perfctr-watchdog.o i8253.o + + obj-$(CONFIG_STACKTRACE) += stacktrace.o + obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o +@@ -47,6 +47,8 @@ + + CFLAGS_vsyscall.o := $(PROFILING) -g0 + ++i8253-y += ../../i386/kernel/i8253.o ++hpet-y += ../../i386/kernel/hpet.o + therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o + bootflag-y += ../../i386/kernel/bootflag.o + cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/apic.c custom-source-rt/arch/x86_64/kernel/apic.c +--- custom-source-rt.orig/arch/x86_64/kernel/apic.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/apic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -39,12 +40,10 @@ + #include + #include + +-int apic_mapped; + int apic_verbosity; +-int apic_runs_main_timer; +-int apic_calibrate_pmtmr __initdata; +- +-int disable_apic_timer __initdata; ++static int apic_mapped; ++static int apic_calibrate_pmtmr __initdata; ++static int disable_apic_timer __initdata; + + /* Local APIC timer works in C2? */ + int local_apic_timer_c2_ok; +@@ -56,14 +55,78 @@ + .flags = IORESOURCE_MEM | IORESOURCE_BUSY, + }; + ++static unsigned int calibration_result; ++ ++static int lapic_next_event(unsigned long delta, ++ struct clock_event_device *evt); ++static void lapic_timer_setup(enum clock_event_mode mode, ++ struct clock_event_device *evt); ++ ++static void lapic_timer_broadcast(cpumask_t mask); ++ ++static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen); ++ ++static struct clock_event_device lapic_clockevent = { ++ .name = "lapic", ++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT ++ | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, ++ .shift = 32, ++ .set_mode = lapic_timer_setup, ++ .set_next_event = lapic_next_event, ++ .broadcast = lapic_timer_broadcast, ++ .rating = 100, ++ .irq = -1, ++}; ++static DEFINE_PER_CPU(struct clock_event_device, lapic_events); ++ ++static int lapic_next_event(unsigned long delta, ++ struct clock_event_device *evt) ++{ ++ apic_write(APIC_TMICT, delta); ++ return 0; ++} ++ ++static void lapic_timer_setup(enum clock_event_mode mode, ++ struct clock_event_device *evt) ++{ ++ unsigned long flags; ++ unsigned int v; ++ ++ /* Lapic used as dummy for broadcast ? */ ++ if (evt->features & CLOCK_EVT_FEAT_DUMMY) ++ return; ++ ++ local_irq_save(flags); ++ ++ switch (mode) { ++ case CLOCK_EVT_MODE_PERIODIC: ++ case CLOCK_EVT_MODE_ONESHOT: ++ __setup_APIC_LVTT(calibration_result, ++ mode != CLOCK_EVT_MODE_PERIODIC, 1); ++ break; ++ case CLOCK_EVT_MODE_UNUSED: ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ v = apic_read(APIC_LVTT); ++ v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); ++ apic_write(APIC_LVTT, v); ++ break; ++ case CLOCK_EVT_MODE_RESUME: ++ /* Nothing to do here */ ++ break; ++ } ++ ++ local_irq_restore(flags); ++} ++ + /* +- * cpu_mask that denotes the CPUs that needs timer interrupt coming in as +- * IPIs in place of local APIC timers ++ * Local APIC timer broadcast function + */ +-static cpumask_t timer_interrupt_broadcast_ipi_mask; +- +-/* Using APIC to generate smp_local_timer_interrupt? */ +-int using_apic_timer __read_mostly = 0; ++static void lapic_timer_broadcast(cpumask_t mask) ++{ ++#ifdef CONFIG_SMP ++ send_IPI_mask(mask, LOCAL_TIMER_VECTOR); ++#endif ++} + + static void apic_pm_activate(void); + +@@ -92,8 +155,9 @@ + void enable_NMI_through_LVT0 (void * dummy) + { + unsigned int v; +- +- v = APIC_DM_NMI; /* unmask and set to NMI */ ++ ++ /* unmask and set to NMI */ ++ v = APIC_DM_NMI; + apic_write(APIC_LVT0, v); + } + +@@ -120,7 +184,7 @@ + * holds up an irq slot - in excessive cases (when multiple + * unexpected vectors occur) that might lock up the APIC + * completely. +- * But don't ack when the APIC is disabled. -AK ++ * But don't ack when the APIC is disabled. -AK + */ + if (!disable_apic) + ack_APIC_irq(); +@@ -453,7 +517,6 @@ + oldvalue, value); + } + +- nmi_watchdog_default(); + setup_apic_nmi_watchdog(NULL); + apic_pm_activate(); + } +@@ -616,7 +679,7 @@ + * Detect and enable local APICs on non-SMP boards. + * Original code written by Keir Fraser. + * On AMD64 we trust the BIOS - if it says no APIC it is likely +- * not correctly set up (usually the APIC timer won't work etc.) ++ * not correctly set up (usually the APIC timer won't work etc.) + */ + + static int __init detect_init_APIC (void) +@@ -757,16 +820,14 @@ + * P5 APIC double write bug. + */ + +-#define APIC_DIVISOR 16 +- +-static void __setup_APIC_LVTT(unsigned int clocks) ++static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) + { + unsigned int lvtt_value, tmp_value; +- int cpu = smp_processor_id(); + +- lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; +- +- if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) ++ lvtt_value = LOCAL_TIMER_VECTOR; ++ if (!oneshot) ++ lvtt_value |= APIC_LVT_TIMER_PERIODIC; ++ if (!irqen) + lvtt_value |= APIC_LVT_MASKED; + + apic_write(APIC_LVTT, lvtt_value); +@@ -779,46 +840,18 @@ + & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) + | APIC_TDR_DIV_16); + +- apic_write(APIC_TMICT, clocks/APIC_DIVISOR); ++ if (!oneshot) ++ apic_write(APIC_TMICT, clocks); + } + +-static void setup_APIC_timer(unsigned int clocks) ++static void setup_APIC_timer(void) + { +- unsigned long flags; ++ struct clock_event_device *levt = &__get_cpu_var(lapic_events); + +- local_irq_save(flags); ++ memcpy(levt, &lapic_clockevent, sizeof(*levt)); ++ levt->cpumask = cpumask_of_cpu(smp_processor_id()); + +- /* wait for irq slice */ +- if (hpet_address && hpet_use_timer) { +- int trigger = hpet_readl(HPET_T0_CMP); +- while (hpet_readl(HPET_COUNTER) >= trigger) +- /* do nothing */ ; +- while (hpet_readl(HPET_COUNTER) < trigger) +- /* do nothing */ ; +- } else { +- int c1, c2; +- outb_p(0x00, 0x43); +- c2 = inb_p(0x40); +- c2 |= inb_p(0x40) << 8; +- do { +- c1 = c2; +- outb_p(0x00, 0x43); +- c2 = inb_p(0x40); +- c2 |= inb_p(0x40) << 8; +- } while (c2 - c1 < 300); +- } +- __setup_APIC_LVTT(clocks); +- /* Turn off PIT interrupt if we use APIC timer as main timer. +- Only works with the PM timer right now +- TBD fix it for HPET too. */ +- if ((pmtmr_ioport != 0) && +- smp_processor_id() == boot_cpu_id && +- apic_runs_main_timer == 1 && +- !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) { +- stop_timer_interrupt(); +- apic_runs_main_timer++; +- } +- local_irq_restore(flags); ++ clockevents_register_device(levt); + } + + /* +@@ -836,17 +869,22 @@ + + #define TICK_COUNT 100000000 + +-static int __init calibrate_APIC_clock(void) ++static void __init calibrate_APIC_clock(void) + { + unsigned apic, apic_start; + unsigned long tsc, tsc_start; + int result; ++ ++ local_irq_disable(); ++ + /* + * Put whatever arbitrary (but long enough) timeout + * value into the APIC clock, we just want to get the + * counter running for calibration. ++ * ++ * No interrupt enable ! + */ +- __setup_APIC_LVTT(4000000000); ++ __setup_APIC_LVTT(250000000, 0, 0); + + apic_start = apic_read(APIC_TMCCT); + #ifdef CONFIG_X86_PM_TIMER +@@ -868,138 +906,75 @@ + result = (apic_start - apic) * 1000L * tsc_khz / + (tsc - tsc_start); + } +- printk("result %d\n", result); + ++ local_irq_enable(); ++ ++ printk(KERN_DEBUG "APIC timer calibration result %d\n", result); + + printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", + result / 1000 / 1000, result / 1000 % 1000); + +- return result * APIC_DIVISOR / HZ; +-} ++ /* Calculate the scaled math multiplication factor */ ++ lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32); ++ lapic_clockevent.max_delta_ns = ++ clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); ++ lapic_clockevent.min_delta_ns = ++ clockevent_delta2ns(0xF, &lapic_clockevent); + +-static unsigned int calibration_result; ++ calibration_result = result / HZ; ++} + + void __init setup_boot_APIC_clock (void) + { +- if (disable_apic_timer) { +- printk(KERN_INFO "Disabling APIC timer\n"); +- return; +- } ++ /* ++ * The local apic timer can be disabled via the kernel commandline. ++ * Register the lapic timer as a dummy clock event source on SMP ++ * systems, so the broadcast mechanism is used. On UP systems simply ++ * ignore it. ++ */ ++ if (disable_apic_timer) { ++ printk(KERN_INFO "Disabling APIC timer\n"); ++ /* No broadcast on UP ! */ ++ if (num_possible_cpus() > 1) ++ setup_APIC_timer(); ++ return; ++ } + + printk(KERN_INFO "Using local APIC timer interrupts.\n"); +- using_apic_timer = 1; +- +- local_irq_disable(); ++ calibrate_APIC_clock(); + +- calibration_result = calibrate_APIC_clock(); + /* +- * Now set up the timer for real. ++ * If nmi_watchdog is set to IO_APIC, we need the ++ * PIT/HPET going. Otherwise register lapic as a dummy ++ * device. + */ +- setup_APIC_timer(calibration_result); ++ if (nmi_watchdog != NMI_IO_APIC) ++ lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; ++ else ++ printk(KERN_WARNING "APIC timer registered as dummy," ++ " due to nmi_watchdog=1!\n"); + +- local_irq_enable(); ++ setup_APIC_timer(); + } + + void __cpuinit setup_secondary_APIC_clock(void) + { +- local_irq_disable(); /* FIXME: Do we need this? --RR */ +- setup_APIC_timer(calibration_result); +- local_irq_enable(); ++ setup_APIC_timer(); + } + +-void disable_APIC_timer(void) +-{ +- if (using_apic_timer) { +- unsigned long v; +- +- v = apic_read(APIC_LVTT); +- /* +- * When an illegal vector value (0-15) is written to an LVT +- * entry and delivery mode is Fixed, the APIC may signal an +- * illegal vector error, with out regard to whether the mask +- * bit is set or whether an interrupt is actually seen on input. +- * +- * Boot sequence might call this function when the LVTT has +- * '0' vector value. So make sure vector field is set to +- * valid value. +- */ +- v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); +- apic_write(APIC_LVTT, v); +- } +-} +- +-void enable_APIC_timer(void) +-{ +- int cpu = smp_processor_id(); +- +- if (using_apic_timer && +- !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { +- unsigned long v; +- +- v = apic_read(APIC_LVTT); +- apic_write(APIC_LVTT, v & ~APIC_LVT_MASKED); +- } +-} +- +-void switch_APIC_timer_to_ipi(void *cpumask) +-{ +- cpumask_t mask = *(cpumask_t *)cpumask; +- int cpu = smp_processor_id(); +- +- if (cpu_isset(cpu, mask) && +- !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { +- disable_APIC_timer(); +- cpu_set(cpu, timer_interrupt_broadcast_ipi_mask); +- } +-} +-EXPORT_SYMBOL(switch_APIC_timer_to_ipi); +- +-void smp_send_timer_broadcast_ipi(void) +-{ +- int cpu = smp_processor_id(); +- cpumask_t mask; +- +- cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask); +- +- if (cpu_isset(cpu, mask)) { +- cpu_clear(cpu, mask); +- add_pda(apic_timer_irqs, 1); +- smp_local_timer_interrupt(); +- } +- +- if (!cpus_empty(mask)) { +- send_IPI_mask(mask, LOCAL_TIMER_VECTOR); +- } +-} +- +-void switch_ipi_to_APIC_timer(void *cpumask) +-{ +- cpumask_t mask = *(cpumask_t *)cpumask; +- int cpu = smp_processor_id(); +- +- if (cpu_isset(cpu, mask) && +- cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { +- cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask); +- enable_APIC_timer(); +- } +-} +-EXPORT_SYMBOL(switch_ipi_to_APIC_timer); +- + int setup_profiling_timer(unsigned int multiplier) + { + return -EINVAL; + } + +-void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, +- unsigned char msg_type, unsigned char mask) ++void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, ++ unsigned char msg_type, unsigned char mask) + { + unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE; + unsigned int v = (mask << 16) | (msg_type << 8) | vector; + apic_write(reg, v); + } + +-#undef APIC_DIVISOR +- + /* + * Local timer interrupt handler. It does both profiling and + * process statistics/rescheduling. +@@ -1012,22 +987,34 @@ + + void smp_local_timer_interrupt(void) + { +- profile_tick(CPU_PROFILING); +-#ifdef CONFIG_SMP +- update_process_times(user_mode(get_irq_regs())); +-#endif +- if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id) +- main_timer_handler(); ++ int cpu = smp_processor_id(); ++ struct clock_event_device *evt = &per_cpu(lapic_events, cpu); ++ + /* +- * We take the 'long' return path, and there every subsystem +- * grabs the appropriate locks (kernel lock/ irq lock). +- * +- * We might want to decouple profiling from the 'long path', +- * and do the profiling totally in assembly. ++ * Normally we should not be here till LAPIC has been initialized but ++ * in some cases like kdump, its possible that there is a pending LAPIC ++ * timer interrupt from previous kernel's context and is delivered in ++ * new kernel the moment interrupts are enabled. + * +- * Currently this isn't too much of an issue (performance wise), +- * we can take more than 100K local irqs per second on a 100 MHz P5. ++ * Interrupts are enabled early and LAPIC is setup much later, hence ++ * its possible that when we get here evt->event_handler is NULL. ++ * Check for event_handler being NULL and discard the interrupt as ++ * spurious. ++ */ ++ if (!evt->event_handler) { ++ printk(KERN_WARNING ++ "Spurious LAPIC timer interrupt on cpu %d\n", cpu); ++ /* Switch it off */ ++ lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); ++ return; ++ } ++ ++ /* ++ * the NMI deadlock-detector uses this. + */ ++ add_pda(apic_timer_irqs, 1); ++ ++ evt->event_handler(evt); + } + + /* +@@ -1043,11 +1030,6 @@ + struct pt_regs *old_regs = set_irq_regs(regs); + + /* +- * the NMI deadlock-detector uses this. +- */ +- add_pda(apic_timer_irqs, 1); +- +- /* + * NOTE! We'd better ACK the irq immediately, + * because timer handling can be slow. + */ +@@ -1127,21 +1109,6 @@ + v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1)); + if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) + ack_APIC_irq(); +- +-#if 0 +- static unsigned long last_warning; +- static unsigned long skipped; +- +- /* see sw-dev-man vol 3, chapter 7.4.13.5 */ +- if (time_before(last_warning+30*HZ,jiffies)) { +- printk(KERN_INFO "spurious APIC interrupt on CPU#%d, %ld skipped.\n", +- smp_processor_id(), skipped); +- last_warning = jiffies; +- skipped = 0; +- } else { +- skipped++; +- } +-#endif + irq_exit(); + } + +@@ -1173,11 +1140,11 @@ + 7: Illegal register address + */ + printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n", +- smp_processor_id(), v , v1); ++ smp_processor_id(), v , v1); + irq_exit(); + } + +-int disable_apic; ++int disable_apic; + + /* + * This initializes the IO-APIC and APIC hardware if this is +@@ -1185,11 +1152,11 @@ + */ + int __init APIC_init_uniprocessor (void) + { +- if (disable_apic) { ++ if (disable_apic) { + printk(KERN_INFO "Apic disabled\n"); +- return -1; ++ return -1; + } +- if (!cpu_has_apic) { ++ if (!cpu_has_apic) { + disable_apic = 1; + printk(KERN_INFO "Apic disabled by BIOS\n"); + return -1; +@@ -1211,8 +1178,8 @@ + return 0; + } + +-static __init int setup_disableapic(char *str) +-{ ++static __init int setup_disableapic(char *str) ++{ + disable_apic = 1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + return 0; +@@ -1220,10 +1187,10 @@ + early_param("disableapic", setup_disableapic); + + /* same as disableapic, for compatibility */ +-static __init int setup_nolapic(char *str) +-{ ++static __init int setup_nolapic(char *str) ++{ + return setup_disableapic(str); +-} ++} + early_param("nolapic", setup_nolapic); + + static int __init parse_lapic_timer_c2_ok(char *arg) +@@ -1233,36 +1200,20 @@ + } + early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); + +-static __init int setup_noapictimer(char *str) +-{ ++static __init int setup_noapictimer(char *str) ++{ + if (str[0] != ' ' && str[0] != 0) + return 0; + disable_apic_timer = 1; + return 1; +-} +- +-static __init int setup_apicmaintimer(char *str) +-{ +- apic_runs_main_timer = 1; +- nohpet = 1; +- return 1; +-} +-__setup("apicmaintimer", setup_apicmaintimer); +- +-static __init int setup_noapicmaintimer(char *str) +-{ +- apic_runs_main_timer = -1; +- return 1; + } +-__setup("noapicmaintimer", setup_noapicmaintimer); ++__setup("noapictimer", setup_noapictimer); + + static __init int setup_apicpmtimer(char *s) + { + apic_calibrate_pmtmr = 1; + notsc_setup(NULL); +- return setup_apicmaintimer(NULL); ++ return 0; + } + __setup("apicpmtimer", setup_apicpmtimer); + +-__setup("noapictimer", setup_noapictimer); +- +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/crash.c custom-source-rt/arch/x86_64/kernel/crash.c +--- custom-source-rt.orig/arch/x86_64/kernel/crash.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/crash.c 2007-10-02 17:31:08.000000000 +0000 +@@ -62,11 +62,6 @@ + return 1; + } + +-static void smp_send_nmi_allbutself(void) +-{ +- send_IPI_allbutself(NMI_VECTOR); +-} +- + /* + * This code is a best effort heuristic to get the + * other cpus to stop executing. So races with +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/early_printk.c custom-source-rt/arch/x86_64/kernel/early_printk.c +--- custom-source-rt.orig/arch/x86_64/kernel/early_printk.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/early_printk.c 2007-10-02 17:31:08.000000000 +0000 +@@ -202,7 +202,7 @@ + + void early_printk(const char *fmt, ...) + { +- char buf[512]; ++ static char buf[512]; + int n; + va_list ap; + +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/entry.S custom-source-rt/arch/x86_64/kernel/entry.S +--- custom-source-rt.orig/arch/x86_64/kernel/entry.S 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/entry.S 2007-10-02 17:31:08.000000000 +0000 +@@ -53,6 +53,47 @@ + + .code64 + ++#ifdef CONFIG_EVENT_TRACE ++ ++ENTRY(mcount) ++ cmpl $0, mcount_enabled ++ jz out ++ ++ push %rbp ++ mov %rsp,%rbp ++ ++ push %r11 ++ push %r10 ++ push %r9 ++ push %r8 ++ push %rdi ++ push %rsi ++ push %rdx ++ push %rcx ++ push %rax ++ ++ mov 0x0(%rbp),%rax ++ mov 0x8(%rbp),%rdi ++ mov 0x8(%rax),%rsi ++ ++ call __trace ++ ++ pop %rax ++ pop %rcx ++ pop %rdx ++ pop %rsi ++ pop %rdi ++ pop %r8 ++ pop %r9 ++ pop %r10 ++ pop %r11 ++ ++ pop %rbp ++out: ++ ret ++ ++#endif ++ + #ifndef CONFIG_PREEMPT + #define retint_kernel retint_restore_args + #endif +@@ -234,7 +275,9 @@ + cmpq $__NR_syscall_max,%rax + ja badsys + movq %r10,%rcx ++ TRACE_SYS_CALL + call *sys_call_table(,%rax,8) # XXX: rip relative ++ TRACE_SYS_RET + movq %rax,RAX-ARGOFFSET(%rsp) + /* + * Syscall return path ending with SYSRET (fast path) +@@ -267,8 +310,8 @@ + /* Handle reschedules */ + /* edx: work, edi: workmask */ + sysret_careful: +- bt $TIF_NEED_RESCHED,%edx +- jnc sysret_signal ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz sysret_signal + TRACE_IRQS_ON + sti + pushq %rdi +@@ -291,7 +334,7 @@ + leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 + xorl %esi,%esi # oldset -> arg2 + call ptregscall_common +-1: movl $_TIF_NEED_RESCHED,%edi ++1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + /* Use IRET because user could have changed frame. This + works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ + cli +@@ -316,7 +359,9 @@ + cmova %rcx,%rax + ja 1f + movq %r10,%rcx /* fixup for C */ ++ TRACE_SYS_CALL + call *sys_call_table(,%rax,8) ++ TRACE_SYS_RET + 1: movq %rax,RAX-ARGOFFSET(%rsp) + /* Use IRET because user could have changed frame */ + +@@ -344,8 +389,8 @@ + /* First do a reschedule test. */ + /* edx: work, edi: workmask */ + int_careful: +- bt $TIF_NEED_RESCHED,%edx +- jnc int_very_careful ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz int_very_careful + TRACE_IRQS_ON + sti + pushq %rdi +@@ -380,7 +425,7 @@ + movq %rsp,%rdi # &ptregs -> arg1 + xorl %esi,%esi # oldset -> arg2 + call do_notify_resume +-1: movl $_TIF_NEED_RESCHED,%edi ++1: movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + int_restore_rest: + RESTORE_REST + cli +@@ -584,8 +629,8 @@ + /* edi: workmask, edx: work */ + retint_careful: + CFI_RESTORE_STATE +- bt $TIF_NEED_RESCHED,%edx +- jnc retint_signal ++ testl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edx ++ jz retint_signal + TRACE_IRQS_ON + sti + pushq %rdi +@@ -611,7 +656,7 @@ + RESTORE_REST + cli + TRACE_IRQS_OFF +- movl $_TIF_NEED_RESCHED,%edi ++ movl $(_TIF_NEED_RESCHED|_TIF_NEED_RESCHED_DELAYED),%edi + GET_THREAD_INFO(%rcx) + jmp retint_check + +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/head64.c custom-source-rt/arch/x86_64/kernel/head64.c +--- custom-source-rt.orig/arch/x86_64/kernel/head64.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/head64.c 2007-10-02 17:31:08.000000000 +0000 +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -25,7 +26,11 @@ + { + pgd_t *pgd = pgd_offset_k(0UL); + pgd_clear(pgd); +- __flush_tlb(); ++ /* ++ * preempt_disable/enable does not work this early in the ++ * bootup yet: ++ */ ++ write_cr3(read_cr3()); + } + + /* Don't add a printk in there. printk relies on the PDA which is not initialized +@@ -58,7 +63,7 @@ + memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); + } + +-void __init x86_64_start_kernel(char * real_mode_data) ++void __init notrace x86_64_start_kernel(char * real_mode_data) + { + int i; + +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/hpet.c custom-source-rt/arch/x86_64/kernel/hpet.c +--- custom-source-rt.orig/arch/x86_64/kernel/hpet.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/hpet.c 1970-01-01 00:00:00.000000000 +0000 +@@ -1,493 +0,0 @@ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define HPET_MASK 0xFFFFFFFF +-#define HPET_SHIFT 22 +- +-/* FSEC = 10^-15 NSEC = 10^-9 */ +-#define FSEC_PER_NSEC 1000000 +- +-int nohpet __initdata; +- +-unsigned long hpet_address; +-unsigned long hpet_period; /* fsecs / HPET clock */ +-unsigned long hpet_tick; /* HPET clocks / interrupt */ +- +-int hpet_use_timer; /* Use counter of hpet for time keeping, +- * otherwise PIT +- */ +- +-#ifdef CONFIG_HPET +-static __init int late_hpet_init(void) +-{ +- struct hpet_data hd; +- unsigned int ntimer; +- +- if (!hpet_address) +- return 0; +- +- memset(&hd, 0, sizeof(hd)); +- +- ntimer = hpet_readl(HPET_ID); +- ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; +- ntimer++; +- +- /* +- * Register with driver. +- * Timer0 and Timer1 is used by platform. +- */ +- hd.hd_phys_address = hpet_address; +- hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); +- hd.hd_nirqs = ntimer; +- hd.hd_flags = HPET_DATA_PLATFORM; +- hpet_reserve_timer(&hd, 0); +-#ifdef CONFIG_HPET_EMULATE_RTC +- hpet_reserve_timer(&hd, 1); +-#endif +- hd.hd_irq[0] = HPET_LEGACY_8254; +- hd.hd_irq[1] = HPET_LEGACY_RTC; +- if (ntimer > 2) { +- struct hpet *hpet; +- struct hpet_timer *timer; +- int i; +- +- hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE); +- timer = &hpet->hpet_timers[2]; +- for (i = 2; i < ntimer; timer++, i++) +- hd.hd_irq[i] = (timer->hpet_config & +- Tn_INT_ROUTE_CNF_MASK) >> +- Tn_INT_ROUTE_CNF_SHIFT; +- +- } +- +- hpet_alloc(&hd); +- return 0; +-} +-fs_initcall(late_hpet_init); +-#endif +- +-int hpet_timer_stop_set_go(unsigned long tick) +-{ +- unsigned int cfg; +- +-/* +- * Stop the timers and reset the main counter. +- */ +- +- cfg = hpet_readl(HPET_CFG); +- cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); +- hpet_writel(cfg, HPET_CFG); +- hpet_writel(0, HPET_COUNTER); +- hpet_writel(0, HPET_COUNTER + 4); +- +-/* +- * Set up timer 0, as periodic with first interrupt to happen at hpet_tick, +- * and period also hpet_tick. +- */ +- if (hpet_use_timer) { +- hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | +- HPET_TN_32BIT, HPET_T0_CFG); +- hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */ +- hpet_writel(hpet_tick, HPET_T0_CMP); /* period */ +- cfg |= HPET_CFG_LEGACY; +- } +-/* +- * Go! +- */ +- +- cfg |= HPET_CFG_ENABLE; +- hpet_writel(cfg, HPET_CFG); +- +- return 0; +-} +- +-static cycle_t read_hpet(void) +-{ +- return (cycle_t)hpet_readl(HPET_COUNTER); +-} +- +-static cycle_t __vsyscall_fn vread_hpet(void) +-{ +- return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); +-} +- +-struct clocksource clocksource_hpet = { +- .name = "hpet", +- .rating = 250, +- .read = read_hpet, +- .mask = (cycle_t)HPET_MASK, +- .mult = 0, /* set below */ +- .shift = HPET_SHIFT, +- .flags = CLOCK_SOURCE_IS_CONTINUOUS, +- .vread = vread_hpet, +-}; +- +-int hpet_arch_init(void) +-{ +- unsigned int id; +- u64 tmp; +- +- if (!hpet_address) +- return -1; +- set_fixmap_nocache(FIX_HPET_BASE, hpet_address); +- __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); +- +-/* +- * Read the period, compute tick and quotient. +- */ +- +- id = hpet_readl(HPET_ID); +- +- if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER)) +- return -1; +- +- hpet_period = hpet_readl(HPET_PERIOD); +- if (hpet_period < 100000 || hpet_period > 100000000) +- return -1; +- +- hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period; +- +- hpet_use_timer = (id & HPET_ID_LEGSUP); +- +- /* +- * hpet period is in femto seconds per cycle +- * so we need to convert this to ns/cyc units +- * aproximated by mult/2^shift +- * +- * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift +- * fsec/cyc * 1ns/1000000fsec * 2^shift = mult +- * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult +- * (fsec/cyc << shift)/1000000 = mult +- * (hpet_period << shift)/FSEC_PER_NSEC = mult +- */ +- tmp = (u64)hpet_period << HPET_SHIFT; +- do_div(tmp, FSEC_PER_NSEC); +- clocksource_hpet.mult = (u32)tmp; +- clocksource_register(&clocksource_hpet); +- +- return hpet_timer_stop_set_go(hpet_tick); +-} +- +-int hpet_reenable(void) +-{ +- return hpet_timer_stop_set_go(hpet_tick); +-} +- +-/* +- * calibrate_tsc() calibrates the processor TSC in a very simple way, comparing +- * it to the HPET timer of known frequency. +- */ +- +-#define TICK_COUNT 100000000 +-#define TICK_MIN 5000 +-#define MAX_TRIES 5 +- +-/* +- * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none +- * occurs between the reads of the hpet & TSC. +- */ +-static void __init read_hpet_tsc(int *hpet, int *tsc) +-{ +- int tsc1, tsc2, hpet1, i; +- +- for (i = 0; i < MAX_TRIES; i++) { +- tsc1 = get_cycles_sync(); +- hpet1 = hpet_readl(HPET_COUNTER); +- tsc2 = get_cycles_sync(); +- if (tsc2 - tsc1 > TICK_MIN) +- break; +- } +- *hpet = hpet1; +- *tsc = tsc2; +-} +- +-unsigned int __init hpet_calibrate_tsc(void) +-{ +- int tsc_start, hpet_start; +- int tsc_now, hpet_now; +- unsigned long flags; +- +- local_irq_save(flags); +- +- read_hpet_tsc(&hpet_start, &tsc_start); +- +- do { +- local_irq_disable(); +- read_hpet_tsc(&hpet_now, &tsc_now); +- local_irq_restore(flags); +- } while ((tsc_now - tsc_start) < TICK_COUNT && +- (hpet_now - hpet_start) < TICK_COUNT); +- +- return (tsc_now - tsc_start) * 1000000000L +- / ((hpet_now - hpet_start) * hpet_period / 1000); +-} +- +-#ifdef CONFIG_HPET_EMULATE_RTC +-/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET +- * is enabled, we support RTC interrupt functionality in software. +- * RTC has 3 kinds of interrupts: +- * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock +- * is updated +- * 2) Alarm Interrupt - generate an interrupt at a specific time of day +- * 3) Periodic Interrupt - generate periodic interrupt, with frequencies +- * 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2) +- * (1) and (2) above are implemented using polling at a frequency of +- * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt +- * overhead. (DEFAULT_RTC_INT_FREQ) +- * For (3), we use interrupts at 64Hz or user specified periodic +- * frequency, whichever is higher. +- */ +-#include +- +-#define DEFAULT_RTC_INT_FREQ 64 +-#define RTC_NUM_INTS 1 +- +-static unsigned long UIE_on; +-static unsigned long prev_update_sec; +- +-static unsigned long AIE_on; +-static struct rtc_time alarm_time; +- +-static unsigned long PIE_on; +-static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ; +-static unsigned long PIE_count; +- +-static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */ +-static unsigned int hpet_t1_cmp; /* cached comparator register */ +- +-int is_hpet_enabled(void) +-{ +- return hpet_address != 0; +-} +- +-/* +- * Timer 1 for RTC, we do not use periodic interrupt feature, +- * even if HPET supports periodic interrupts on Timer 1. +- * The reason being, to set up a periodic interrupt in HPET, we need to +- * stop the main counter. And if we do that everytime someone diables/enables +- * RTC, we will have adverse effect on main kernel timer running on Timer 0. +- * So, for the time being, simulate the periodic interrupt in software. +- * +- * hpet_rtc_timer_init() is called for the first time and during subsequent +- * interuppts reinit happens through hpet_rtc_timer_reinit(). +- */ +-int hpet_rtc_timer_init(void) +-{ +- unsigned int cfg, cnt; +- unsigned long flags; +- +- if (!is_hpet_enabled()) +- return 0; +- /* +- * Set the counter 1 and enable the interrupts. +- */ +- if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) +- hpet_rtc_int_freq = PIE_freq; +- else +- hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; +- +- local_irq_save(flags); +- +- cnt = hpet_readl(HPET_COUNTER); +- cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); +- hpet_writel(cnt, HPET_T1_CMP); +- hpet_t1_cmp = cnt; +- +- cfg = hpet_readl(HPET_T1_CFG); +- cfg &= ~HPET_TN_PERIODIC; +- cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; +- hpet_writel(cfg, HPET_T1_CFG); +- +- local_irq_restore(flags); +- +- return 1; +-} +- +-static void hpet_rtc_timer_reinit(void) +-{ +- unsigned int cfg, cnt, ticks_per_int, lost_ints; +- +- if (unlikely(!(PIE_on | AIE_on | UIE_on))) { +- cfg = hpet_readl(HPET_T1_CFG); +- cfg &= ~HPET_TN_ENABLE; +- hpet_writel(cfg, HPET_T1_CFG); +- return; +- } +- +- if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ)) +- hpet_rtc_int_freq = PIE_freq; +- else +- hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; +- +- /* It is more accurate to use the comparator value than current count.*/ +- ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq; +- hpet_t1_cmp += ticks_per_int; +- hpet_writel(hpet_t1_cmp, HPET_T1_CMP); +- +- /* +- * If the interrupt handler was delayed too long, the write above tries +- * to schedule the next interrupt in the past and the hardware would +- * not interrupt until the counter had wrapped around. +- * So we have to check that the comparator wasn't set to a past time. +- */ +- cnt = hpet_readl(HPET_COUNTER); +- if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) { +- lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1; +- /* Make sure that, even with the time needed to execute +- * this code, the next scheduled interrupt has been moved +- * back to the future: */ +- lost_ints++; +- +- hpet_t1_cmp += lost_ints * ticks_per_int; +- hpet_writel(hpet_t1_cmp, HPET_T1_CMP); +- +- if (PIE_on) +- PIE_count += lost_ints; +- +- if (printk_ratelimit()) +- printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", +- hpet_rtc_int_freq); +- } +-} +- +-/* +- * The functions below are called from rtc driver. +- * Return 0 if HPET is not being used. +- * Otherwise do the necessary changes and return 1. +- */ +-int hpet_mask_rtc_irq_bit(unsigned long bit_mask) +-{ +- if (!is_hpet_enabled()) +- return 0; +- +- if (bit_mask & RTC_UIE) +- UIE_on = 0; +- if (bit_mask & RTC_PIE) +- PIE_on = 0; +- if (bit_mask & RTC_AIE) +- AIE_on = 0; +- +- return 1; +-} +- +-int hpet_set_rtc_irq_bit(unsigned long bit_mask) +-{ +- int timer_init_reqd = 0; +- +- if (!is_hpet_enabled()) +- return 0; +- +- if (!(PIE_on | AIE_on | UIE_on)) +- timer_init_reqd = 1; +- +- if (bit_mask & RTC_UIE) { +- UIE_on = 1; +- } +- if (bit_mask & RTC_PIE) { +- PIE_on = 1; +- PIE_count = 0; +- } +- if (bit_mask & RTC_AIE) { +- AIE_on = 1; +- } +- +- if (timer_init_reqd) +- hpet_rtc_timer_init(); +- +- return 1; +-} +- +-int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) +-{ +- if (!is_hpet_enabled()) +- return 0; +- +- alarm_time.tm_hour = hrs; +- alarm_time.tm_min = min; +- alarm_time.tm_sec = sec; +- +- return 1; +-} +- +-int hpet_set_periodic_freq(unsigned long freq) +-{ +- if (!is_hpet_enabled()) +- return 0; +- +- PIE_freq = freq; +- PIE_count = 0; +- +- return 1; +-} +- +-int hpet_rtc_dropped_irq(void) +-{ +- if (!is_hpet_enabled()) +- return 0; +- +- return 1; +-} +- +-irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +-{ +- struct rtc_time curr_time; +- unsigned long rtc_int_flag = 0; +- int call_rtc_interrupt = 0; +- +- hpet_rtc_timer_reinit(); +- +- if (UIE_on | AIE_on) { +- rtc_get_rtc_time(&curr_time); +- } +- if (UIE_on) { +- if (curr_time.tm_sec != prev_update_sec) { +- /* Set update int info, call real rtc int routine */ +- call_rtc_interrupt = 1; +- rtc_int_flag = RTC_UF; +- prev_update_sec = curr_time.tm_sec; +- } +- } +- if (PIE_on) { +- PIE_count++; +- if (PIE_count >= hpet_rtc_int_freq/PIE_freq) { +- /* Set periodic int info, call real rtc int routine */ +- call_rtc_interrupt = 1; +- rtc_int_flag |= RTC_PF; +- PIE_count = 0; +- } +- } +- if (AIE_on) { +- if ((curr_time.tm_sec == alarm_time.tm_sec) && +- (curr_time.tm_min == alarm_time.tm_min) && +- (curr_time.tm_hour == alarm_time.tm_hour)) { +- /* Set alarm int info, call real rtc int routine */ +- call_rtc_interrupt = 1; +- rtc_int_flag |= RTC_AF; +- } +- } +- if (call_rtc_interrupt) { +- rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8)); +- rtc_interrupt(rtc_int_flag, dev_id); +- } +- return IRQ_HANDLED; +-} +-#endif +- +-static int __init nohpet_setup(char *s) +-{ +- nohpet = 1; +- return 1; +-} +- +-__setup("nohpet", nohpet_setup); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/i8259.c custom-source-rt/arch/x86_64/kernel/i8259.c +--- custom-source-rt.orig/arch/x86_64/kernel/i8259.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/i8259.c 2007-10-02 17:31:08.000000000 +0000 +@@ -96,8 +96,8 @@ + */ + + static int i8259A_auto_eoi; +-DEFINE_SPINLOCK(i8259A_lock); + static void mask_and_ack_8259A(unsigned int); ++DEFINE_RAW_SPINLOCK(i8259A_lock); + + static struct irq_chip i8259A_chip = { + .name = "XT-PIC", +@@ -395,7 +395,8 @@ + * IRQ2 is cascade interrupt to second interrupt controller + */ + +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; ++static struct irqaction irq2 = { no_action, IRQF_NODELAY, CPU_MASK_NONE, "cascade", NULL, NULL}; ++ + DEFINE_PER_CPU(vector_irq_t, vector_irq) = { + [0 ... IRQ0_VECTOR - 1] = -1, + [IRQ0_VECTOR] = 0, +@@ -460,47 +461,6 @@ + void invalidate_interrupt7(void); + void thermal_interrupt(void); + void threshold_interrupt(void); +-void i8254_timer_resume(void); +- +-static void setup_timer_hardware(void) +-{ +- outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ +- udelay(10); +- outb_p(LATCH & 0xff , 0x40); /* LSB */ +- udelay(10); +- outb(LATCH >> 8 , 0x40); /* MSB */ +-} +- +-static int timer_resume(struct sys_device *dev) +-{ +- setup_timer_hardware(); +- return 0; +-} +- +-void i8254_timer_resume(void) +-{ +- setup_timer_hardware(); +-} +- +-static struct sysdev_class timer_sysclass = { +- set_kset_name("timer_pit"), +- .resume = timer_resume, +-}; +- +-static struct sys_device device_timer = { +- .id = 0, +- .cls = &timer_sysclass, +-}; +- +-static int __init init_timer_sysfs(void) +-{ +- int error = sysdev_class_register(&timer_sysclass); +- if (!error) +- error = sysdev_register(&device_timer); +- return error; +-} +- +-device_initcall(init_timer_sysfs); + + void __init init_IRQ(void) + { +@@ -551,12 +511,6 @@ + set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); + set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); + +- /* +- * Set the clock to HZ Hz, we already have a valid +- * vector now: +- */ +- setup_timer_hardware(); +- + if (!acpi_ioapic) + setup_irq(2, &irq2); + } +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/io_apic.c custom-source-rt/arch/x86_64/kernel/io_apic.c +--- custom-source-rt.orig/arch/x86_64/kernel/io_apic.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/io_apic.c 2007-10-02 17:31:08.000000000 +0000 +@@ -90,8 +90,8 @@ + /* Where if anywhere is the i8259 connect in external int mode */ + static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + +-static DEFINE_SPINLOCK(ioapic_lock); +-DEFINE_SPINLOCK(vector_lock); ++static DEFINE_RAW_SPINLOCK(ioapic_lock); ++DEFINE_RAW_SPINLOCK(vector_lock); + + /* + * # of IRQ routing registers +@@ -178,6 +178,9 @@ + reg ACTION; \ + io_apic_modify(entry->apic, reg); \ + FINAL; \ ++ /* Force POST flush by reading: */ \ ++ reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ ++ \ + if (!entry->next) \ + break; \ + entry = irq_2_pin + entry->next; \ +@@ -322,10 +325,11 @@ + static void name##_IO_APIC_irq (unsigned int irq) \ + __DO_ACTION(R, ACTION, FINAL) + +-DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic) ) +- /* mask = 1 */ +-DO_ACTION( __unmask, 0, &= 0xfffeffff, ) +- /* mask = 0 */ ++DO_ACTION( __mask, 0, |= 0x00010000, ) /* mask = 1 */ ++DO_ACTION( __unmask, 0, &= 0xfffeffff, ) /* mask = 0 */ ++ ++DO_ACTION( __pcix_mask, 0, &= 0xffff7fff, ) /* edge */ ++DO_ACTION( __pcix_unmask, 0, = (reg & 0xfffeffff) | 0x00008000, ) /* level */ + + static void mask_IO_APIC_irq (unsigned int irq) + { +@@ -344,6 +348,23 @@ + __unmask_IO_APIC_irq(irq); + spin_unlock_irqrestore(&ioapic_lock, flags); + } ++static void pcix_mask_IO_APIC_irq (unsigned int irq) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __pcix_mask_IO_APIC_irq(irq); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++} ++ ++static void pcix_unmask_IO_APIC_irq (unsigned int irq) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioapic_lock, flags); ++ __pcix_unmask_IO_APIC_irq(irq); ++ spin_unlock_irqrestore(&ioapic_lock, flags); ++} + + static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) + { +@@ -771,15 +792,18 @@ + + + static struct irq_chip ioapic_chip; ++static struct irq_chip pcix_ioapic_chip; + +-static void ioapic_register_intr(int irq, unsigned long trigger) ++static void ioapic_register_intr(int irq, unsigned long trigger, int pcix) + { ++ struct irq_chip *chip = pcix ? &pcix_ioapic_chip : &ioapic_chip; ++ + if (trigger) +- set_irq_chip_and_handler_name(irq, &ioapic_chip, +- handle_fasteoi_irq, "fasteoi"); ++ set_irq_chip_and_handler_name(irq, chip, handle_fasteoi_irq, ++ pcix ? "pcix-fasteoi" : "fasteoi"); + else +- set_irq_chip_and_handler_name(irq, &ioapic_chip, +- handle_edge_irq, "edge"); ++ set_irq_chip_and_handler_name(irq, chip, handle_edge_irq, ++ pcix ? "pcix-edge" : "edge"); + } + + static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, +@@ -823,7 +847,7 @@ + if (trigger) + entry.mask = 1; + +- ioapic_register_intr(irq, trigger); ++ ioapic_register_intr(irq, trigger, apic > 0); + if (irq < 16) + disable_8259A_irq(irq); + +@@ -1405,7 +1429,8 @@ + irq_complete_move(irq); + #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) + /* If we are moving the irq we need to mask it */ +- if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { ++ if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING) && ++ !(irq_desc[irq].status & IRQ_INPROGRESS)) { + do_unmask_irq = 1; + mask_IO_APIC_irq(irq); + } +@@ -1424,14 +1449,27 @@ + } + + static struct irq_chip ioapic_chip __read_mostly = { +- .name = "IO-APIC", +- .startup = startup_ioapic_irq, +- .mask = mask_IO_APIC_irq, +- .unmask = unmask_IO_APIC_irq, +- .ack = ack_apic_edge, +- .eoi = ack_apic_level, ++ .name = "IO-APIC", ++ .startup = startup_ioapic_irq, ++ .mask = mask_IO_APIC_irq, ++ .unmask = unmask_IO_APIC_irq, ++ .ack = ack_apic_edge, ++ .eoi = ack_apic_level, ++#ifdef CONFIG_SMP ++ .set_affinity = set_ioapic_affinity_irq, ++#endif ++ .retrigger = ioapic_retrigger_irq, ++}; ++ ++static struct irq_chip pcix_ioapic_chip __read_mostly = { ++ .name = "IO-APIC", ++ .startup = startup_ioapic_irq, ++ .mask = pcix_mask_IO_APIC_irq, ++ .unmask = pcix_unmask_IO_APIC_irq, ++ .ack = ack_apic_edge, ++ .eoi = ack_apic_level, + #ifdef CONFIG_SMP +- .set_affinity = set_ioapic_affinity_irq, ++ .set_affinity = set_ioapic_affinity_irq, + #endif + .retrigger = ioapic_retrigger_irq, + }; +@@ -1628,7 +1666,6 @@ + */ + unmask_IO_APIC_irq(0); + if (!no_timer_check && timer_irq_works()) { +- nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + disable_8259A_irq(0); + setup_nmi(); +@@ -1654,7 +1691,6 @@ + setup_ExtINT_IRQ0_pin(apic2, pin2, cfg->vector); + if (timer_irq_works()) { + apic_printk(APIC_VERBOSE," works.\n"); +- nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + setup_nmi(); + } +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/irq.c custom-source-rt/arch/x86_64/kernel/irq.c +--- custom-source-rt.orig/arch/x86_64/kernel/irq.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/irq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -111,10 +111,18 @@ + unsigned vector = ~regs->orig_rax; + unsigned irq; + ++ irq_show_regs_callback(smp_processor_id(), regs); ++ + exit_idle(); + irq_enter(); + irq = __get_cpu_var(vector_irq)[vector]; + ++#ifdef CONFIG_EVENT_TRACE ++ if (irq == trace_user_trigger_irq) ++ user_trace_start(); ++#endif ++ trace_special(regs->rip, irq, 0); ++ + #ifdef CONFIG_DEBUG_STACKOVERFLOW + stack_overflow_check(regs); + #endif +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/kprobes.c custom-source-rt/arch/x86_64/kernel/kprobes.c +--- custom-source-rt.orig/arch/x86_64/kernel/kprobes.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/kprobes.c 2007-10-02 17:31:08.000000000 +0000 +@@ -658,11 +658,9 @@ + case DIE_GPF: + case DIE_PAGE_FAULT: + /* kprobe_running() needs smp_processor_id() */ +- preempt_disable(); +- if (kprobe_running() && ++ if (per_cpu(current_kprobe, raw_smp_processor_id()) && + kprobe_fault_handler(args->regs, args->trapnr)) + ret = NOTIFY_STOP; +- preempt_enable(); + break; + default: + break; +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/mce_amd.c custom-source-rt/arch/x86_64/kernel/mce_amd.c +--- custom-source-rt.orig/arch/x86_64/kernel/mce_amd.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/mce_amd.c 2007-10-02 17:31:08.000000000 +0000 +@@ -157,9 +157,9 @@ + high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; + wrmsr(address, low, high); + +- setup_APIC_extened_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, +- THRESHOLD_APIC_VECTOR, +- K8_APIC_EXT_INT_MSG_FIX, 0); ++ setup_APIC_extended_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, ++ THRESHOLD_APIC_VECTOR, ++ K8_APIC_EXT_INT_MSG_FIX, 0); + + threshold_defaults.address = address; + threshold_restart_bank(&threshold_defaults, 0, 0); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/nmi.c custom-source-rt/arch/x86_64/kernel/nmi.c +--- custom-source-rt.orig/arch/x86_64/kernel/nmi.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/nmi.c 2007-10-02 17:31:08.000000000 +0000 +@@ -22,11 +22,13 @@ + #include + #include + #include ++#include + + #include + #include + #include + #include ++#include + + int unknown_nmi_panic; + int nmi_watchdog_enabled; +@@ -44,7 +46,7 @@ + int panic_on_timeout; + + unsigned int nmi_watchdog = NMI_DEFAULT; +-static unsigned int nmi_hz = HZ; ++static unsigned int nmi_hz = 1000; + + static DEFINE_PER_CPU(short, wd_enabled); + +@@ -52,7 +54,7 @@ + static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); + + /* Run after command line and cpu_init init, but before all other checks */ +-void nmi_watchdog_default(void) ++static inline void nmi_watchdog_default(void) + { + if (nmi_watchdog != NMI_DEFAULT) + return; +@@ -68,7 +70,9 @@ + */ + static __init void nmi_cpu_busy(void *data) + { ++#ifndef CONFIG_PREEMPT_RT + local_irq_enable_in_hardirq(); ++#endif + /* Intentionally don't use cpu_relax here. This is + to make sure that the performance counter really ticks, + even if there is a simulator or similar that catches the +@@ -302,7 +306,7 @@ + unsigned cpu; + + /* +- * Tell other CPUs to reset their alert counters. We cannot ++ * Tell other CPUs to reset their alert counters. We cannot + * do it ourselves because the alert count increase is not + * atomic. + */ +@@ -310,16 +314,54 @@ + per_cpu(nmi_touch, cpu) = 1; + } + +- touch_softlockup_watchdog(); ++ touch_softlockup_watchdog(); ++} ++ ++int nmi_show_regs[NR_CPUS]; ++ ++void nmi_show_all_regs(void) ++{ ++ int i; ++ ++ if (system_state == SYSTEM_BOOTING) ++ return; ++ ++ smp_send_nmi_allbutself(); ++ ++ for_each_online_cpu(i) ++ nmi_show_regs[i] = 1; ++ ++ for_each_online_cpu(i) { ++ while (nmi_show_regs[i] == 1) ++ barrier(); ++ } ++} ++ ++static DEFINE_RAW_SPINLOCK(nmi_print_lock); ++ ++notrace void irq_show_regs_callback(int cpu, struct pt_regs *regs) ++{ ++ if (!nmi_show_regs[cpu]) ++ return; ++ ++ nmi_show_regs[cpu] = 0; ++ spin_lock(&nmi_print_lock); ++ printk(KERN_WARNING "NMI show regs on CPU#%d:\n", cpu); ++ printk(KERN_WARNING "apic_timer_irqs: %d\n", read_pda(apic_timer_irqs)); ++ show_regs(regs); ++ spin_unlock(&nmi_print_lock); + } + +-int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) ++int notrace __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) + { + int sum; + int touched = 0; + int cpu = smp_processor_id(); + int rc = 0; + ++ irq_show_regs_callback(cpu, regs); ++ __profile_tick(CPU_PROFILING, regs); ++ + /* check for other users first */ + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { +@@ -328,6 +370,7 @@ + } + + sum = read_pda(apic_timer_irqs); ++ + if (__get_cpu_var(nmi_touch)) { + __get_cpu_var(nmi_touch) = 0; + touched = 1; +@@ -356,9 +399,20 @@ + * wait a few IRQs (5 seconds) before doing the oops ... + */ + local_inc(&__get_cpu_var(alert_counter)); +- if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) ++ if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { ++ int i; ++ ++ for_each_online_cpu(i) { ++ if (i == cpu) ++ continue; ++ nmi_show_regs[i] = 1; ++ while (nmi_show_regs[i] == 1) ++ cpu_relax(); ++ } ++ + die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs, + panic_on_timeout); ++ } + } else { + __get_cpu_var(last_irq_sum) = sum; + local_set(&__get_cpu_var(alert_counter), 0); +@@ -461,6 +515,13 @@ + } + } + ++void smp_send_nmi_allbutself(void) ++{ ++#ifdef CONFIG_SMP ++ send_IPI_allbutself(NMI_VECTOR); ++#endif ++} ++ + EXPORT_SYMBOL(nmi_active); + EXPORT_SYMBOL(nmi_watchdog); + EXPORT_SYMBOL(touch_nmi_watchdog); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/process.c custom-source-rt/arch/x86_64/kernel/process.c +--- custom-source-rt.orig/arch/x86_64/kernel/process.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/process.c 2007-10-02 17:31:08.000000000 +0000 +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -115,7 +116,7 @@ + */ + smp_mb(); + local_irq_disable(); +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + /* Enables interrupts one instruction before HLT. + x86 special cases this so there is no race. */ + safe_halt(); +@@ -201,12 +202,14 @@ + current_thread_info()->status |= TS_POLLING; + /* endless idle loop with no priority at all */ + while (1) { +- while (!need_resched()) { ++ while (!need_resched() && !need_resched_delayed()) { + void (*idle)(void); + + if (__get_cpu_var(cpu_idle_state)) + __get_cpu_var(cpu_idle_state) = 0; + ++ tick_nohz_stop_sched_tick(); ++ + rmb(); + idle = pm_idle; + if (!idle) +@@ -227,9 +230,14 @@ + __exit_idle(); + } + +- preempt_enable_no_resched(); +- schedule(); ++ tick_nohz_restart_sched_tick(); ++ local_irq_disable(); ++ trace_preempt_exit_idle(); ++ __preempt_enable_no_resched(); ++ __schedule(); + preempt_disable(); ++ trace_preempt_enter_idle(); ++ local_irq_enable(); + } + } + +@@ -245,10 +253,10 @@ + */ + void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) + { +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) + __mwait(eax, ecx); + } + } +@@ -256,12 +264,13 @@ + /* Default MONITOR/MWAIT with no hints, used for default C1 state */ + static void mwait_idle(void) + { +- if (!need_resched()) { ++ if (!need_resched() && !need_resched_delayed()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); +- if (!need_resched()) ++ if (!need_resched() && !need_resched_delayed()) { ++ trace_hardirqs_on(); + __sti_mwait(0, 0); +- else ++ } else + local_irq_enable(); + } else { + local_irq_enable(); +@@ -367,7 +376,7 @@ + struct thread_struct *t = &me->thread; + + if (me->thread.io_bitmap_ptr) { +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); ++ struct tss_struct *tss; + + kfree(t->io_bitmap_ptr); + t->io_bitmap_ptr = NULL; +@@ -375,6 +384,7 @@ + /* + * Careful, clear this in the TSS too: + */ ++ tss = &per_cpu(init_tss, get_cpu()); + memset(tss->io_bitmap, 0xff, t->io_bitmap_max); + t->io_bitmap_max = 0; + put_cpu(); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/setup64.c custom-source-rt/arch/x86_64/kernel/setup64.c +--- custom-source-rt.orig/arch/x86_64/kernel/setup64.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/setup64.c 2007-10-02 17:31:08.000000000 +0000 +@@ -114,7 +114,7 @@ + } + } + +-void pda_init(int cpu) ++void notrace pda_init(int cpu) + { + struct x8664_pda *pda = cpu_pda(cpu); + +@@ -191,7 +191,7 @@ + * 'CPU state barrier', nothing should get across. + * A lot of state is already set up in PDA init. + */ +-void __cpuinit cpu_init (void) ++void __cpuinit notrace cpu_init (void) + { + int cpu = stack_smp_processor_id(); + struct tss_struct *t = &per_cpu(init_tss, cpu); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/signal.c custom-source-rt/arch/x86_64/kernel/signal.c +--- custom-source-rt.orig/arch/x86_64/kernel/signal.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/signal.c 2007-10-02 17:31:08.000000000 +0000 +@@ -395,6 +395,13 @@ + int signr; + sigset_t *oldset; + ++#ifdef CONFIG_PREEMPT_RT ++ /* ++ * Fully-preemptible kernel does not need interrupts disabled: ++ */ ++ local_irq_enable(); ++ preempt_check_resched(); ++#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/smp.c custom-source-rt/arch/x86_64/kernel/smp.c +--- custom-source-rt.orig/arch/x86_64/kernel/smp.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/smp.c 2007-10-02 17:31:08.000000000 +0000 +@@ -56,7 +56,7 @@ + struct mm_struct *flush_mm; + unsigned long flush_va; + #define FLUSH_ALL -1ULL +- spinlock_t tlbstate_lock; ++ raw_spinlock_t tlbstate_lock; + }; + char pad[SMP_CACHE_BYTES]; + } ____cacheline_aligned; +@@ -295,10 +295,20 @@ + } + + /* ++ * this function sends a 'reschedule' IPI to all other CPUs. ++ * This is used when RT tasks are starving and other CPUs ++ * might be able to run them: ++ */ ++void smp_send_reschedule_allbutself(void) ++{ ++ send_IPI_allbutself(RESCHEDULE_VECTOR); ++} ++ ++/* + * Structure and data for smp_call_function(). This is designed to minimise + * static memory requirements. It also looks cleaner. + */ +-static DEFINE_SPINLOCK(call_lock); ++static DEFINE_RAW_SPINLOCK(call_lock); + + struct call_data_struct { + void (*func) (void *info); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/smpboot.c custom-source-rt/arch/x86_64/kernel/smpboot.c +--- custom-source-rt.orig/arch/x86_64/kernel/smpboot.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/smpboot.c 2007-10-02 17:31:08.000000000 +0000 +@@ -223,8 +223,6 @@ + local_irq_disable(); + Dprintk("Stack at about %p\n",&cpuid); + +- disable_APIC_timer(); +- + /* + * Save our processor parameters + */ +@@ -318,7 +316,7 @@ + /* + * Setup code on secondary processor (after comming out of the trampoline) + */ +-void __cpuinit start_secondary(void) ++void __cpuinit notrace start_secondary(void) + { + /* + * Dont put anything before smp_callin(), SMP +@@ -333,8 +331,8 @@ + barrier(); + + /* +- * Check TSC sync first: +- */ ++ * Check TSC sync first: ++ */ + check_tsc_sync_target(); + + Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); +@@ -348,8 +346,6 @@ + enable_8259A_irq(0); + } + +- enable_APIC_timer(); +- + /* + * The sibling maps must be set before turing the online map on for + * this cpu +@@ -854,7 +850,6 @@ + */ + void __init smp_prepare_cpus(unsigned int max_cpus) + { +- nmi_watchdog_default(); + current_cpu_data = boot_cpu_data; + current_thread_info()->cpu = 0; /* needed? */ + set_cpu_sibling_map(0); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/time.c custom-source-rt/arch/x86_64/kernel/time.c +--- custom-source-rt.orig/arch/x86_64/kernel/time.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/time.c 2007-10-02 17:31:08.000000000 +0000 +@@ -28,11 +28,13 @@ + #include + #include + #include ++#include ++ + #ifdef CONFIG_ACPI + #include /* for PM timer frequency */ + #include + #endif +-#include ++#include + #include + #include + #include +@@ -45,11 +47,8 @@ + #include + #include + +-static char *timename = NULL; +- + DEFINE_SPINLOCK(rtc_lock); + EXPORT_SYMBOL(rtc_lock); +-DEFINE_SPINLOCK(i8253_lock); + + volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; + +@@ -79,8 +78,9 @@ + * sheet for details. + */ + +-static void set_rtc_mmss(unsigned long nowtime) ++static int set_rtc_mmss(unsigned long nowtime) + { ++ int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char control, freq_select; + +@@ -120,6 +120,7 @@ + if (abs(real_minutes - cmos_minutes) >= 30) { + printk(KERN_WARNING "time.c: can't update CMOS clock " + "from %d to %d\n", cmos_minutes, real_minutes); ++ retval = -1; + } else { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); +@@ -139,67 +140,23 @@ + CMOS_WRITE(freq_select, RTC_FREQ_SELECT); + + spin_unlock(&rtc_lock); +-} + ++ return retval; ++} + +-void main_timer_handler(void) ++int update_persistent_clock(struct timespec now) + { +- static unsigned long rtc_update = 0; +-/* +- * Here we are in the timer irq handler. We have irqs locally disabled (so we +- * don't need spin_lock_irqsave()) but we don't know if the timer_bh is running +- * on the other CPU, so we need a lock. We also need to lock the vsyscall +- * variables, because both do_timer() and us change them -arca+vojtech +- */ +- +- write_seqlock(&xtime_lock); +- +-/* +- * Do the timer stuff. +- */ +- +- do_timer(1); +-#ifndef CONFIG_SMP +- update_process_times(user_mode(get_irq_regs())); +-#endif +- +-/* +- * In the SMP case we use the local APIC timer interrupt to do the profiling, +- * except when we simulate SMP mode on a uniprocessor system, in that case we +- * have to call the local interrupt handler. +- */ +- +- if (!using_apic_timer) +- smp_local_timer_interrupt(); +- +-/* +- * If we have an externally synchronized Linux clock, then update CMOS clock +- * accordingly every ~11 minutes. set_rtc_mmss() will be called in the jiffy +- * closest to exactly 500 ms before the next second. If the update fails, we +- * don't care, as it'll be updated on the next turn, and the problem (time way +- * off) isn't likely to go away much sooner anyway. +- */ +- +- if (ntp_synced() && xtime.tv_sec > rtc_update && +- abs(xtime.tv_nsec - 500000000) <= tick_nsec / 2) { +- set_rtc_mmss(xtime.tv_sec); +- rtc_update = xtime.tv_sec + 660; +- } +- +- write_sequnlock(&xtime_lock); ++ return set_rtc_mmss(now.tv_sec); + } + +-static irqreturn_t timer_interrupt(int irq, void *dev_id) ++static irqreturn_t timer_event_interrupt(int irq, void *dev_id) + { +- if (apic_runs_main_timer > 1) +- return IRQ_HANDLED; +- main_timer_handler(); +- if (using_apic_timer) +- smp_send_timer_broadcast_ipi(); ++ global_clock_event->event_handler(global_clock_event); ++ + return IRQ_HANDLED; + } + +-static unsigned long get_cmos_time(void) ++unsigned long read_persistent_clock(void) + { + unsigned int year, mon, day, hour, min, sec; + unsigned long flags; +@@ -226,7 +183,7 @@ + /* + * We know that x86-64 always uses BCD format, no need to check the + * config register. +- */ ++ */ + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); +@@ -239,11 +196,11 @@ + BCD_TO_BIN(century); + year += century * 100; + printk(KERN_INFO "Extended CMOS year: %d\n", century * 100); +- } else { ++ } else { + /* + * x86-64 systems only exists since 2002. + * This will work up to Dec 31, 2100 +- */ ++ */ + year += 2000; + } + +@@ -255,143 +212,63 @@ + #define TICK_COUNT 100000000 + static unsigned int __init tsc_calibrate_cpu_khz(void) + { +- int tsc_start, tsc_now; +- int i, no_ctr_free; +- unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0; +- unsigned long flags; +- +- for (i = 0; i < 4; i++) +- if (avail_to_resrv_perfctr_nmi_bit(i)) +- break; +- no_ctr_free = (i == 4); +- if (no_ctr_free) { +- i = 3; +- rdmsrl(MSR_K7_EVNTSEL3, evntsel3); +- wrmsrl(MSR_K7_EVNTSEL3, 0); +- rdmsrl(MSR_K7_PERFCTR3, pmc3); +- } else { +- reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i); +- reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i); +- } +- local_irq_save(flags); +- /* start meauring cycles, incrementing from 0 */ +- wrmsrl(MSR_K7_PERFCTR0 + i, 0); +- wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76); +- rdtscl(tsc_start); +- do { +- rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); +- tsc_now = get_cycles_sync(); +- } while ((tsc_now - tsc_start) < TICK_COUNT); +- +- local_irq_restore(flags); +- if (no_ctr_free) { +- wrmsrl(MSR_K7_EVNTSEL3, 0); +- wrmsrl(MSR_K7_PERFCTR3, pmc3); +- wrmsrl(MSR_K7_EVNTSEL3, evntsel3); +- } else { +- release_perfctr_nmi(MSR_K7_PERFCTR0 + i); +- release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); +- } +- +- return pmc_now * tsc_khz / (tsc_now - tsc_start); +-} +- +-/* +- * pit_calibrate_tsc() uses the speaker output (channel 2) of +- * the PIT. This is better than using the timer interrupt output, +- * because we can read the value of the speaker with just one inb(), +- * where we need three i/o operations for the interrupt channel. +- * We count how many ticks the TSC does in 50 ms. +- */ +- +-static unsigned int __init pit_calibrate_tsc(void) +-{ +- unsigned long start, end; +- unsigned long flags; +- +- spin_lock_irqsave(&i8253_lock, flags); +- +- outb((inb(0x61) & ~0x02) | 0x01, 0x61); +- +- outb(0xb0, 0x43); +- outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42); +- outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42); +- start = get_cycles_sync(); +- while ((inb(0x61) & 0x20) == 0); +- end = get_cycles_sync(); +- +- spin_unlock_irqrestore(&i8253_lock, flags); +- +- return (end - start) / 50; +-} +- +-#define PIT_MODE 0x43 +-#define PIT_CH0 0x40 +- +-static void __pit_init(int val, u8 mode) +-{ ++ int tsc_start, tsc_now; ++ int i, no_ctr_free; ++ unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0; + unsigned long flags; + +- spin_lock_irqsave(&i8253_lock, flags); +- outb_p(mode, PIT_MODE); +- outb_p(val & 0xff, PIT_CH0); /* LSB */ +- outb_p(val >> 8, PIT_CH0); /* MSB */ +- spin_unlock_irqrestore(&i8253_lock, flags); +-} +- +-void __init pit_init(void) +-{ +- __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ +-} +- +-void pit_stop_interrupt(void) +-{ +- __pit_init(0, 0x30); /* mode 0 */ +-} +- +-void stop_timer_interrupt(void) +-{ +- char *name; +- if (hpet_address) { +- name = "HPET"; +- hpet_timer_stop_set_go(0); ++ for (i = 0; i < 4; i++) ++ if (avail_to_resrv_perfctr_nmi_bit(i)) ++ break; ++ no_ctr_free = (i == 4); ++ if (no_ctr_free) { ++ i = 3; ++ rdmsrl(MSR_K7_EVNTSEL3, evntsel3); ++ wrmsrl(MSR_K7_EVNTSEL3, 0); ++ rdmsrl(MSR_K7_PERFCTR3, pmc3); + } else { +- name = "PIT"; +- pit_stop_interrupt(); ++ reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i); ++ reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i); + } +- printk(KERN_INFO "timer: %s interrupt stopped.\n", name); ++ local_irq_save(flags); ++ /* start meauring cycles, incrementing from 0 */ ++ wrmsrl(MSR_K7_PERFCTR0 + i, 0); ++ wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76); ++ rdtscl(tsc_start); ++ do { ++ rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); ++ tsc_now = get_cycles_sync(); ++ } while ((tsc_now - tsc_start) < TICK_COUNT); ++ ++ local_irq_restore(flags); ++ if (no_ctr_free) { ++ wrmsrl(MSR_K7_EVNTSEL3, 0); ++ wrmsrl(MSR_K7_PERFCTR3, pmc3); ++ wrmsrl(MSR_K7_EVNTSEL3, evntsel3); ++ } else { ++ release_perfctr_nmi(MSR_K7_PERFCTR0 + i); ++ release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); ++ } ++ ++ return pmc_now * tsc_khz / (tsc_now - tsc_start); + } + + static struct irqaction irq0 = { +- .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_IRQPOLL, ++ .handler = timer_event_interrupt, ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | ++ IRQF_NODELAY, + .mask = CPU_MASK_NONE, +- .name = "timer" ++ .name = "timer" + }; + + void __init time_init(void) + { +- if (nohpet) +- hpet_address = 0; +- xtime.tv_sec = get_cmos_time(); +- xtime.tv_nsec = 0; +- +- set_normalized_timespec(&wall_to_monotonic, +- -xtime.tv_sec, -xtime.tv_nsec); +- +- if (hpet_arch_init()) +- hpet_address = 0; +- +- if (hpet_use_timer) { +- /* set tick_nsec to use the proper rate for HPET */ +- tick_nsec = TICK_NSEC_HPET; +- tsc_khz = hpet_calibrate_tsc(); +- timename = "HPET"; +- } else { +- pit_init(); +- tsc_khz = pit_calibrate_tsc(); +- timename = "PIT"; +- } ++ if (!hpet_enable()) ++ setup_pit_timer(); ++ ++ setup_irq(0, &irq0); ++ ++ tsc_calibrate(); + + cpu_khz = tsc_khz; + if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && +@@ -411,79 +288,4 @@ + printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + init_tsc_clocksource(); +- +- setup_irq(0, &irq0); + } +- +- +-static long clock_cmos_diff; +-static unsigned long sleep_start; +- +-/* +- * sysfs support for the timer. +- */ +- +-static int timer_suspend(struct sys_device *dev, pm_message_t state) +-{ +- /* +- * Estimate time zone so that set_time can update the clock +- */ +- long cmos_time = get_cmos_time(); +- +- clock_cmos_diff = -cmos_time; +- clock_cmos_diff += get_seconds(); +- sleep_start = cmos_time; +- return 0; +-} +- +-static int timer_resume(struct sys_device *dev) +-{ +- unsigned long flags; +- unsigned long sec; +- unsigned long ctime = get_cmos_time(); +- long sleep_length = (ctime - sleep_start) * HZ; +- +- if (sleep_length < 0) { +- printk(KERN_WARNING "Time skew detected in timer resume!\n"); +- /* The time after the resume must not be earlier than the time +- * before the suspend or some nasty things will happen +- */ +- sleep_length = 0; +- ctime = sleep_start; +- } +- if (hpet_address) +- hpet_reenable(); +- else +- i8254_timer_resume(); +- +- sec = ctime + clock_cmos_diff; +- write_seqlock_irqsave(&xtime_lock,flags); +- xtime.tv_sec = sec; +- xtime.tv_nsec = 0; +- jiffies += sleep_length; +- write_sequnlock_irqrestore(&xtime_lock,flags); +- touch_softlockup_watchdog(); +- return 0; +-} +- +-static struct sysdev_class timer_sysclass = { +- .resume = timer_resume, +- .suspend = timer_suspend, +- set_kset_name("timer"), +-}; +- +-/* XXX this sysfs stuff should probably go elsewhere later -john */ +-static struct sys_device device_timer = { +- .id = 0, +- .cls = &timer_sysclass, +-}; +- +-static int time_init_device(void) +-{ +- int error = sysdev_class_register(&timer_sysclass); +- if (!error) +- error = sysdev_register(&device_timer); +- return error; +-} +- +-device_initcall(time_init_device); +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/traps.c custom-source-rt/arch/x86_64/kernel/traps.c +--- custom-source-rt.orig/arch/x86_64/kernel/traps.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/traps.c 2007-10-02 17:31:08.000000000 +0000 +@@ -215,7 +215,7 @@ + unsigned long *stack, + struct stacktrace_ops *ops, void *data) + { +- const unsigned cpu = get_cpu(); ++ const unsigned cpu = raw_smp_processor_id(); + unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; + unsigned used = 0; + struct thread_info *tinfo; +@@ -306,7 +306,6 @@ + tinfo = task_thread_info(tsk); + HANDLE_STACK (valid_stack_ptr(tinfo, stack)); + #undef HANDLE_STACK +- put_cpu(); + } + EXPORT_SYMBOL(dump_trace); + +@@ -343,9 +342,13 @@ + void + show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) + { ++ pause_on_oops_head(); + printk("\nCall Trace:\n"); + dump_trace(tsk, regs, stack, &print_trace_ops, NULL); + printk("\n"); ++ pause_on_oops_tail(); ++ debug_show_held_locks(tsk); ++ print_traces(tsk); + } + + static void +@@ -353,7 +356,7 @@ + { + unsigned long *stack; + int i; +- const int cpu = smp_processor_id(); ++ const int cpu = raw_smp_processor_id(); + unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); + unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); + +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/tsc.c custom-source-rt/arch/x86_64/kernel/tsc.c +--- custom-source-rt.orig/arch/x86_64/kernel/tsc.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/tsc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -6,7 +6,9 @@ + #include + #include + #include ++#include + ++#include + #include + + static int notsc __initdata = 0; +@@ -61,25 +63,9 @@ + * first tick after the change will be slightly wrong. + */ + +-#include +- +-static unsigned int cpufreq_delayed_issched = 0; +-static unsigned int cpufreq_init = 0; +-static struct work_struct cpufreq_delayed_get_work; +- +-static void handle_cpufreq_delayed_get(struct work_struct *v) +-{ +- unsigned int cpu; +- for_each_online_cpu(cpu) { +- cpufreq_get(cpu); +- } +- cpufreq_delayed_issched = 0; +-} +- +-static unsigned int ref_freq = 0; +-static unsigned long loops_per_jiffy_ref = 0; +- +-static unsigned long tsc_khz_ref = 0; ++static unsigned int ref_freq; ++static unsigned long loops_per_jiffy_ref; ++static unsigned long tsc_khz_ref; + + static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +@@ -125,10 +111,8 @@ + + static int __init cpufreq_tsc(void) + { +- INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get); +- if (!cpufreq_register_notifier(&time_cpufreq_notifier_block, +- CPUFREQ_TRANSITION_NOTIFIER)) +- cpufreq_init = 1; ++ cpufreq_register_notifier(&time_cpufreq_notifier_block, ++ CPUFREQ_TRANSITION_NOTIFIER); + return 0; + } + +@@ -136,7 +120,93 @@ + + #endif + +-static int tsc_unstable = 0; ++#define MAX_RETRIES 5 ++#define SMI_TRESHOLD 50000 ++ ++/* ++ * Read TSC and the reference counters. Take care of SMI disturbance ++ */ ++static unsigned long __init tsc_read_refs(unsigned long *pm, ++ unsigned long *hpet) ++{ ++ unsigned long t1, t2; ++ int i; ++ ++ for (i = 0; i < MAX_RETRIES; i++) { ++ t1 = get_cycles_sync(); ++ if (hpet) ++ *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; ++ else ++ *pm = acpi_pm_read_early(); ++ t2 = get_cycles_sync(); ++ if ((t2 - t1) < SMI_TRESHOLD) ++ return t2; ++ } ++ return ULONG_MAX; ++} ++ ++/** ++ * tsc_calibrate - calibrate the tsc on boot ++ */ ++void __init tsc_calibrate(void) ++{ ++ unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2; ++ int hpet = is_hpet_enabled(); ++ ++ local_irq_save(flags); ++ ++ tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); ++ ++ outb((inb(0x61) & ~0x02) | 0x01, 0x61); ++ ++ outb(0xb0, 0x43); ++ outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); ++ outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); ++ tr1 = get_cycles_sync(); ++ while ((inb(0x61) & 0x20) == 0); ++ tr2 = get_cycles_sync(); ++ ++ tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); ++ ++ local_irq_restore(flags); ++ ++ /* ++ * Preset the result with the raw and inaccurate PIT ++ * calibration value ++ */ ++ tsc_khz = (tr2 - tr1) / 50; ++ ++ /* hpet or pmtimer available ? */ ++ if (!hpet && !pm1 && !pm2) { ++ printk(KERN_INFO "TSC calibrated against PIT\n"); ++ return; ++ } ++ ++ /* Check, whether the sampling was disturbed by an SMI */ ++ if (tsc1 == ULONG_MAX || tsc2 == ULONG_MAX) { ++ printk(KERN_WARNING "TSC calibration disturbed by SMI, " ++ "using PIT calibration result\n"); ++ return; ++ } ++ ++ tsc2 = (tsc2 - tsc1) * 1000000L; ++ ++ if (hpet) { ++ printk(KERN_INFO "TSC calibrated against HPET\n"); ++ if (hpet2 < hpet1) ++ hpet2 += 0x100000000; ++ hpet2 -= hpet1; ++ tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000; ++ } else { ++ printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); ++ if (pm2 < pm1) ++ pm2 += ACPI_PM_OVRRUN; ++ pm2 -= pm1; ++ tsc1 = (pm2 * 1000000000) / PMTMR_TICKS_PER_SEC; ++ } ++ ++ tsc_khz = tsc2 / tsc1; ++} + + /* + * Make an educated guess if the TSC is trustworthy and synchronized +@@ -153,17 +223,18 @@ + #endif + /* Most intel systems have synchronized TSCs except for + multi node systems */ +- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { ++ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { + #ifdef CONFIG_ACPI + /* But TSC doesn't tick in C3 so don't use it there */ +- if (acpi_gbl_FADT.header.length > 0 && acpi_gbl_FADT.C3latency < 1000) ++ if (acpi_gbl_FADT.header.length > 0 && ++ acpi_gbl_FADT.C3latency < 1000) + return 1; + #endif +- return 0; ++ return 0; + } + +- /* Assume multi socket systems are not synchronized */ +- return num_present_cpus() > 1; ++ /* Assume multi socket systems are not synchronized */ ++ return num_present_cpus() > 1; + } + + int __init notsc_setup(char *s) +@@ -176,13 +247,13 @@ + + + /* clock source code: */ +-static cycle_t read_tsc(void) ++static notrace cycle_t read_tsc(void) + { + cycle_t ret = (cycle_t)get_cycles_sync(); + return ret; + } + +-static cycle_t __vsyscall_fn vread_tsc(void) ++static notrace cycle_t __vsyscall_fn vread_tsc(void) + { + cycle_t ret = (cycle_t)get_cycles_sync(); + return ret; +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/tsc_sync.c custom-source-rt/arch/x86_64/kernel/tsc_sync.c +--- custom-source-rt.orig/arch/x86_64/kernel/tsc_sync.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/tsc_sync.c 2007-10-02 17:31:08.000000000 +0000 +@@ -33,7 +33,7 @@ + * we want to have the fastest, inlined, non-debug version + * of a critical section, to be able to prove TSC time-warps: + */ +-static __cpuinitdata raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; ++static __cpuinitdata __raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; + static __cpuinitdata cycles_t last_tsc; + static __cpuinitdata cycles_t max_warp; + static __cpuinitdata int nr_warps; +@@ -97,6 +97,7 @@ + */ + void __cpuinit check_tsc_sync_source(int cpu) + { ++ unsigned long flags; + int cpus = 2; + + /* +@@ -117,8 +118,11 @@ + /* + * Wait for the target to arrive: + */ ++ local_save_flags(flags); ++ local_irq_enable(); + while (atomic_read(&start_count) != cpus-1) + cpu_relax(); ++ local_irq_restore(flags); + /* + * Trigger the target to continue into the measurement too: + */ +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/vsyscall.c custom-source-rt/arch/x86_64/kernel/vsyscall.c +--- custom-source-rt.orig/arch/x86_64/kernel/vsyscall.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/vsyscall.c 2007-10-02 17:31:08.000000000 +0000 +@@ -43,7 +43,7 @@ + #include + #include + +-#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) ++#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) notrace + #define __syscall_clobber "r11","rcx","memory" + #define __pa_vsymbol(x) \ + ({unsigned long v; \ +@@ -58,7 +58,7 @@ + * Try to keep this structure as small as possible to avoid cache line ping pongs + */ + struct vsyscall_gtod_data_t { +- seqlock_t lock; ++ raw_seqlock_t lock; + + /* open coded 'struct timespec' */ + time_t wall_time_sec; +@@ -68,7 +68,7 @@ + struct timezone sys_tz; + struct { /* extract of a clocksource struct */ + cycle_t (*vread)(void); +- cycle_t cycle_last; ++ cycle_t cycle_last, cycle_accumulated; + cycle_t mask; + u32 mult; + u32 shift; +@@ -78,7 +78,7 @@ + + struct vsyscall_gtod_data_t __vsyscall_gtod_data __section_vsyscall_gtod_data = + { +- .lock = SEQLOCK_UNLOCKED, ++ .lock = __RAW_SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), + .sysctl_enabled = 1, + }; + +@@ -93,6 +93,7 @@ + vsyscall_gtod_data.clock.mask = clock->mask; + vsyscall_gtod_data.clock.mult = clock->mult; + vsyscall_gtod_data.clock.shift = clock->shift; ++ vsyscall_gtod_data.clock.cycle_accumulated = clock->cycle_accumulated; + vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; + vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; + vsyscall_gtod_data.sys_tz = sys_tz; +@@ -128,10 +129,29 @@ + + static __always_inline void do_vgettimeofday(struct timeval * tv) + { +- cycle_t now, base, mask, cycle_delta; ++ cycle_t now, base, accumulated, mask, cycle_delta; + unsigned seq; + unsigned long mult, shift, nsec; + cycle_t (*vread)(void); ++ ++ if (likely(__vsyscall_gtod_data.sysctl_enabled == 2)) { ++ struct timeval tmp; ++ ++ do { ++ barrier(); ++ tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; ++ tv->tv_usec = __vsyscall_gtod_data.wall_time_nsec; ++ barrier(); ++ tmp.tv_sec = __vsyscall_gtod_data.wall_time_sec; ++ tmp.tv_usec = __vsyscall_gtod_data.wall_time_nsec; ++ ++ } while (tmp.tv_usec != tv->tv_usec || ++ tmp.tv_sec != tv->tv_sec); ++ ++ tv->tv_usec /= NSEC_PER_USEC; ++ return; ++ } ++ + do { + seq = read_seqbegin(&__vsyscall_gtod_data.lock); + +@@ -142,6 +162,7 @@ + } + now = vread(); + base = __vsyscall_gtod_data.clock.cycle_last; ++ accumulated = __vsyscall_gtod_data.clock.cycle_accumulated; + mask = __vsyscall_gtod_data.clock.mask; + mult = __vsyscall_gtod_data.clock.mult; + shift = __vsyscall_gtod_data.clock.shift; +@@ -152,6 +173,7 @@ + + /* calculate interval: */ + cycle_delta = (now - base) & mask; ++ cycle_delta += accumulated; + /* convert to nsecs: */ + nsec += (cycle_delta * mult) >> shift; + +diff -Nur custom-source-rt.orig/arch/x86_64/kernel/x8664_ksyms.c custom-source-rt/arch/x86_64/kernel/x8664_ksyms.c +--- custom-source-rt.orig/arch/x86_64/kernel/x8664_ksyms.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/kernel/x8664_ksyms.c 2007-10-02 17:31:08.000000000 +0000 +@@ -11,10 +11,12 @@ + + EXPORT_SYMBOL(kernel_thread); + +-EXPORT_SYMBOL(__down_failed); +-EXPORT_SYMBOL(__down_failed_interruptible); +-EXPORT_SYMBOL(__down_failed_trylock); +-EXPORT_SYMBOL(__up_wakeup); ++#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK ++EXPORT_SYMBOL(__compat_down_failed); ++EXPORT_SYMBOL(__compat_down_failed_interruptible); ++EXPORT_SYMBOL(__compat_down_failed_trylock); ++EXPORT_SYMBOL(__compat_up_wakeup); ++#endif + + EXPORT_SYMBOL(__get_user_1); + EXPORT_SYMBOL(__get_user_2); +diff -Nur custom-source-rt.orig/arch/x86_64/lib/thunk.S custom-source-rt/arch/x86_64/lib/thunk.S +--- custom-source-rt.orig/arch/x86_64/lib/thunk.S 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/lib/thunk.S 2007-10-02 17:31:08.000000000 +0000 +@@ -40,15 +40,31 @@ + thunk rwsem_wake_thunk,rwsem_wake + thunk rwsem_downgrade_thunk,rwsem_downgrade_wake + #endif +- +- thunk __down_failed,__down +- thunk_retrax __down_failed_interruptible,__down_interruptible +- thunk_retrax __down_failed_trylock,__down_trylock +- thunk __up_wakeup,__up ++ ++#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK ++ thunk __compat_down_failed,__compat_down ++ thunk_retrax __compat_down_failed_interruptible,__compat_down_interruptible ++ thunk_retrax __compat_down_failed_trylock,__compat_down_trylock ++ thunk __compat_up_wakeup,__compat_up ++#endif + + #ifdef CONFIG_TRACE_IRQFLAGS +- thunk trace_hardirqs_on_thunk,trace_hardirqs_on +- thunk trace_hardirqs_off_thunk,trace_hardirqs_off ++ /* put return address in rdi (arg1) */ ++ .macro thunk_ra name,func ++ .globl \name ++\name: ++ CFI_STARTPROC ++ SAVE_ARGS ++ /* SAVE_ARGS pushs 9 elements */ ++ /* the next element would be the rip */ ++ movq 9*8(%rsp), %rdi ++ call \func ++ jmp restore ++ CFI_ENDPROC ++ .endm ++ ++ thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller ++ thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller + #endif + + /* SAVE_ARGS below is used only for the .cfi directives it contains. */ +diff -Nur custom-source-rt.orig/arch/x86_64/mm/fault.c custom-source-rt/arch/x86_64/mm/fault.c +--- custom-source-rt.orig/arch/x86_64/mm/fault.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/mm/fault.c 2007-10-02 17:31:08.000000000 +0000 +@@ -381,7 +381,7 @@ + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ +- if (unlikely(in_atomic() || !mm)) ++ if (unlikely(in_atomic() || !mm || current->pagefault_disabled)) + goto bad_area_nosemaphore; + + again: +diff -Nur custom-source-rt.orig/arch/x86_64/mm/init.c custom-source-rt/arch/x86_64/mm/init.c +--- custom-source-rt.orig/arch/x86_64/mm/init.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/arch/x86_64/mm/init.c 2007-10-02 17:31:08.000000000 +0000 +@@ -53,7 +53,7 @@ + + static unsigned long dma_reserve __initdata; + +-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_PER_CPU_LOCKED(struct mmu_gather, mmu_gathers); + + /* + * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the +diff -Nur custom-source-rt.orig/block/cfq-iosched.c custom-source-rt/block/cfq-iosched.c +--- custom-source-rt.orig/block/cfq-iosched.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/block/cfq-iosched.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1280,6 +1280,8 @@ + /* + * no prio set, place us in the middle of the BE classes + */ ++ if (tsk->policy == SCHED_IDLE) ++ goto set_class_idle; + cfqq->ioprio = task_nice_ioprio(tsk); + cfqq->ioprio_class = IOPRIO_CLASS_BE; + break; +@@ -1292,6 +1294,7 @@ + cfqq->ioprio_class = IOPRIO_CLASS_BE; + break; + case IOPRIO_CLASS_IDLE: ++ set_class_idle: + cfqq->ioprio_class = IOPRIO_CLASS_IDLE; + cfqq->ioprio = 7; + cfq_clear_cfqq_idle_window(cfqq); +diff -Nur custom-source-rt.orig/block/ll_rw_blk.c custom-source-rt/block/ll_rw_blk.c +--- custom-source-rt.orig/block/ll_rw_blk.c 2007-10-02 17:10:23.000000000 +0000 ++++ custom-source-rt/block/ll_rw_blk.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1550,7 +1550,7 @@ + */ + void blk_plug_device(request_queue_t *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + /* + * don't plug a stopped queue, it must be paired with blk_start_queue() +@@ -1573,7 +1573,7 @@ + */ + int blk_remove_plug(request_queue_t *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) + return 0; +@@ -1665,7 +1665,7 @@ + **/ + void blk_start_queue(request_queue_t *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON_NONRT(!irqs_disabled()); + + clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags); + +diff -Nur custom-source-rt.orig/drivers/Makefile custom-source-rt/drivers/Makefile +--- custom-source-rt.orig/drivers/Makefile 2007-08-21 05:45:44.000000000 +0000 ++++ custom-source-rt/drivers/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -70,6 +70,7 @@ + obj-$(CONFIG_MCA) += mca/ + obj-$(CONFIG_EISA) += eisa/ + obj-$(CONFIG_CPU_FREQ) += cpufreq/ ++obj-$(CONFIG_CPU_IDLE) += cpuidle/ + obj-$(CONFIG_MMC) += mmc/ + obj-$(CONFIG_MSS) += mmc/ + obj-$(CONFIG_NEW_LEDS) += leds/ +diff -Nur custom-source-rt.orig/drivers/acpi/ec.c custom-source-rt/drivers/acpi/ec.c +--- custom-source-rt.orig/drivers/acpi/ec.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/acpi/ec.c 2007-10-02 17:31:08.000000000 +0000 +@@ -420,7 +420,19 @@ + atomic_inc(&ec->event_count); + + if (acpi_ec_mode == EC_INTR) { ++#if 0 + wake_up(&ec->wait); ++#else ++ // hack ... ++ if (waitqueue_active(&ec->wait)) { ++ struct task_struct *task; ++ ++ task = list_entry(ec->wait.task_list.next, ++ wait_queue_t, task_list)->private; ++ if (task) ++ wake_up_process(task); ++ } ++#endif + } + + value = acpi_ec_read_status(ec); +diff -Nur custom-source-rt.orig/drivers/acpi/hardware/hwregs.c custom-source-rt/drivers/acpi/hardware/hwregs.c +--- custom-source-rt.orig/drivers/acpi/hardware/hwregs.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/acpi/hardware/hwregs.c 2007-10-02 17:31:08.000000000 +0000 +@@ -73,7 +73,7 @@ + ACPI_BITMASK_ALL_FIXED_STATUS, + (u16) acpi_gbl_FADT.xpm1a_event_block.address)); + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, +@@ -98,7 +98,7 @@ + status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); + + unlock_and_exit: +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + return_ACPI_STATUS(status); + } + +@@ -331,7 +331,7 @@ + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + + /* Always do a register read first so we can insert the new bits */ + +@@ -441,7 +441,7 @@ + + unlock_and_exit: + +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + + /* Normalize the value that was read */ + +@@ -481,7 +481,7 @@ + ACPI_FUNCTION_TRACE(hw_register_read); + + if (ACPI_MTX_LOCK == use_lock) { +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + } + + switch (register_id) { +@@ -560,7 +560,7 @@ + + unlock_and_exit: + if (ACPI_MTX_LOCK == use_lock) { +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + } + + if (ACPI_SUCCESS(status)) { +@@ -606,7 +606,7 @@ + ACPI_FUNCTION_TRACE(hw_register_write); + + if (ACPI_MTX_LOCK == use_lock) { +- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); ++ spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); + } + + switch (register_id) { +@@ -730,7 +730,7 @@ + + unlock_and_exit: + if (ACPI_MTX_LOCK == use_lock) { +- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); ++ spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); + } + + return_ACPI_STATUS(status); +diff -Nur custom-source-rt.orig/drivers/acpi/osl.c custom-source-rt/drivers/acpi/osl.c +--- custom-source-rt.orig/drivers/acpi/osl.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/acpi/osl.c 2007-10-02 17:31:08.000000000 +0000 +@@ -811,13 +811,13 @@ + acpi_status + acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) + { +- struct semaphore *sem = NULL; ++ struct compat_semaphore *sem = NULL; + + +- sem = acpi_os_allocate(sizeof(struct semaphore)); ++ sem = acpi_os_allocate(sizeof(struct compat_semaphore)); + if (!sem) + return AE_NO_MEMORY; +- memset(sem, 0, sizeof(struct semaphore)); ++ memset(sem, 0, sizeof(struct compat_semaphore)); + + sema_init(sem, initial_units); + +@@ -840,7 +840,7 @@ + + acpi_status acpi_os_delete_semaphore(acpi_handle handle) + { +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + + + if (!sem) +@@ -868,7 +868,7 @@ + acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) + { + acpi_status status = AE_OK; +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + int ret = 0; + + +@@ -955,7 +955,7 @@ + */ + acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) + { +- struct semaphore *sem = (struct semaphore *)handle; ++ struct compat_semaphore *sem = (struct compat_semaphore *)handle; + + + if (!sem || (units < 1)) +@@ -1122,6 +1122,17 @@ + + EXPORT_SYMBOL(max_cstate); + ++void (*acpi_do_set_cstate_limit)(void); ++EXPORT_SYMBOL(acpi_do_set_cstate_limit); ++ ++void acpi_set_cstate_limit(unsigned int new_limit) ++{ ++ max_cstate = new_limit; ++ if (acpi_do_set_cstate_limit) ++ acpi_do_set_cstate_limit(); ++} ++EXPORT_SYMBOL(acpi_set_cstate_limit); ++ + /* + * Acquire a spinlock. + * +diff -Nur custom-source-rt.orig/drivers/acpi/processor_core.c custom-source-rt/drivers/acpi/processor_core.c +--- custom-source-rt.orig/drivers/acpi/processor_core.c 2007-10-02 17:10:24.000000000 +0000 ++++ custom-source-rt/drivers/acpi/processor_core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1024,11 +1025,15 @@ + + acpi_processor_ppc_init(); + ++ cpuidle_register_driver(&acpi_idle_driver); ++ acpi_do_set_cstate_limit = acpi_max_cstate_changed; + return 0; + } + + static void __exit acpi_processor_exit(void) + { ++ acpi_do_set_cstate_limit = NULL; ++ cpuidle_unregister_driver(&acpi_idle_driver); + + acpi_processor_ppc_exit(); + +diff -Nur custom-source-rt.orig/drivers/acpi/processor_idle.c custom-source-rt/drivers/acpi/processor_idle.c +--- custom-source-rt.orig/drivers/acpi/processor_idle.c 2007-10-02 17:10:24.000000000 +0000 ++++ custom-source-rt/drivers/acpi/processor_idle.c 2007-10-02 17:33:11.000000000 +0000 +@@ -40,6 +40,7 @@ + #include /* need_resched() */ + #include + #include ++#include + + /* + * Include the apic definitions for x86 to have the APIC timer related defines +@@ -62,25 +63,34 @@ + #define _COMPONENT ACPI_PROCESSOR_COMPONENT + ACPI_MODULE_NAME("processor_idle"); + #define ACPI_PROCESSOR_FILE_POWER "power" +-#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) +-#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +-#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ +-static void (*pm_idle_save) (void) __read_mostly; +-module_param(max_cstate, uint, 0644); ++#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) ++#define C2_OVERHEAD 1 /* 1us */ ++#define C3_OVERHEAD 1 /* 1us */ ++ ++void acpi_max_cstate_changed(void) ++{ ++ /* Driver will reset devices' max cstate limit */ ++ cpuidle_force_redetect_devices(&acpi_idle_driver); ++} ++ ++static int change_max_cstate(const char *val, struct kernel_param *kp) ++{ ++ int max; ++ ++ max = simple_strtol(val, NULL, 0); ++ if (!max) ++ return -EINVAL; ++ max_cstate = max; ++ if (acpi_do_set_cstate_limit) ++ acpi_do_set_cstate_limit(); ++ return 0; ++} ++ ++module_param_call(max_cstate, change_max_cstate, param_get_uint, &max_cstate, 0644); + + static unsigned int nocst __read_mostly; + module_param(nocst, uint, 0000); + +-/* +- * bm_history -- bit-mask with a bit per jiffy of bus-master activity +- * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms +- * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms +- * 100 HZ: 0x0000000F: 4 jiffies = 40ms +- * reduce history for more aggressive entry into C3 +- */ +-static unsigned int bm_history __read_mostly = +- (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); +-module_param(bm_history, uint, 0644); + /* -------------------------------------------------------------------------- + Power Management + -------------------------------------------------------------------------- */ +@@ -166,88 +176,6 @@ + {}, + }; + +-static inline u32 ticks_elapsed(u32 t1, u32 t2) +-{ +- if (t2 >= t1) +- return (t2 - t1); +- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) +- return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); +- else +- return ((0xFFFFFFFF - t1) + t2); +-} +- +-static void +-acpi_processor_power_activate(struct acpi_processor *pr, +- struct acpi_processor_cx *new) +-{ +- struct acpi_processor_cx *old; +- +- if (!pr || !new) +- return; +- +- old = pr->power.state; +- +- if (old) +- old->promotion.count = 0; +- new->demotion.count = 0; +- +- /* Cleanup from old state. */ +- if (old) { +- switch (old->type) { +- case ACPI_STATE_C3: +- /* Disable bus master reload */ +- if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) +- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); +- break; +- } +- } +- +- /* Prepare to use new state. */ +- switch (new->type) { +- case ACPI_STATE_C3: +- /* Enable bus master reload */ +- if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) +- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); +- break; +- } +- +- pr->power.state = new; +- +- return; +-} +- +-static void acpi_safe_halt(void) +-{ +- current_thread_info()->status &= ~TS_POLLING; +- /* +- * TS_POLLING-cleared state must be visible before we +- * test NEED_RESCHED: +- */ +- smp_mb(); +- if (!need_resched()) +- safe_halt(); +- current_thread_info()->status |= TS_POLLING; +-} +- +-static atomic_t c3_cpu_count; +- +-/* Common C-state entry for C2, C3, .. */ +-static void acpi_cstate_enter(struct acpi_processor_cx *cstate) +-{ +- if (cstate->space_id == ACPI_CSTATE_FFH) { +- /* Call into architectural FFH based C-state */ +- acpi_processor_ffh_cstate_enter(cstate); +- } else { +- int unused; +- /* IO port based C-state */ +- inb(cstate->address); +- /* Dummy wait op - must do something useless after P_LVL2 read +- because chipsets cannot guarantee that STPCLK# signal +- gets asserted in time to freeze execution properly. */ +- unused = inl(acpi_gbl_FADT.xpm_timer_block.address); +- } +-} +- + #ifdef ARCH_APICTIMER_STOPS_ON_C3 + + /* +@@ -275,21 +203,12 @@ + + static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) + { +-#ifdef CONFIG_GENERIC_CLOCKEVENTS + unsigned long reason; + + reason = pr->power.timer_broadcast_on_state < INT_MAX ? + CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF; + + clockevents_notify(reason, &pr->id); +-#else +- cpumask_t mask = cpumask_of_cpu(pr->id); +- +- if (pr->power.timer_broadcast_on_state < INT_MAX) +- on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); +- else +- on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); +-#endif + } + + /* Power(C) State timer broadcast control */ +@@ -297,8 +216,6 @@ + struct acpi_processor_cx *cx, + int broadcast) + { +-#ifdef CONFIG_GENERIC_CLOCKEVENTS +- + int state = cx - pr->power.states; + + if (state >= pr->power.timer_broadcast_on_state) { +@@ -308,7 +225,6 @@ + CLOCK_EVT_NOTIFY_BROADCAST_EXIT; + clockevents_notify(reason, &pr->id); + } +-#endif + } + + #else +@@ -341,377 +257,6 @@ + return 0; + } + +-static void acpi_processor_idle(void) +-{ +- struct acpi_processor *pr = NULL; +- struct acpi_processor_cx *cx = NULL; +- struct acpi_processor_cx *next_state = NULL; +- int sleep_ticks = 0; +- u32 t1, t2 = 0; +- +- /* +- * Interrupts must be disabled during bus mastering calculations and +- * for C2/C3 transitions. +- */ +- local_irq_disable(); +- +- pr = processors[smp_processor_id()]; +- if (!pr) { +- local_irq_enable(); +- return; +- } +- +- /* +- * Check whether we truly need to go idle, or should +- * reschedule: +- */ +- if (unlikely(need_resched())) { +- local_irq_enable(); +- return; +- } +- +- cx = pr->power.state; +- if (!cx || acpi_idle_suspend) { +- if (pm_idle_save) +- pm_idle_save(); +- else +- acpi_safe_halt(); +- return; +- } +- +- /* +- * Check BM Activity +- * ----------------- +- * Check for bus mastering activity (if required), record, and check +- * for demotion. +- */ +- if (pr->flags.bm_check) { +- u32 bm_status = 0; +- unsigned long diff = jiffies - pr->power.bm_check_timestamp; +- +- if (diff > 31) +- diff = 31; +- +- pr->power.bm_activity <<= diff; +- +- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); +- if (bm_status) { +- pr->power.bm_activity |= 0x1; +- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); +- } +- /* +- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect +- * the true state of bus mastering activity; forcing us to +- * manually check the BMIDEA bit of each IDE channel. +- */ +- else if (errata.piix4.bmisx) { +- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) +- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) +- pr->power.bm_activity |= 0x1; +- } +- +- pr->power.bm_check_timestamp = jiffies; +- +- /* +- * If bus mastering is or was active this jiffy, demote +- * to avoid a faulty transition. Note that the processor +- * won't enter a low-power state during this call (to this +- * function) but should upon the next. +- * +- * TBD: A better policy might be to fallback to the demotion +- * state (use it for this quantum only) istead of +- * demoting -- and rely on duration as our sole demotion +- * qualification. This may, however, introduce DMA +- * issues (e.g. floppy DMA transfer overrun/underrun). +- */ +- if ((pr->power.bm_activity & 0x1) && +- cx->demotion.threshold.bm) { +- local_irq_enable(); +- next_state = cx->demotion.state; +- goto end; +- } +- } +- +-#ifdef CONFIG_HOTPLUG_CPU +- /* +- * Check for P_LVL2_UP flag before entering C2 and above on +- * an SMP system. We do it here instead of doing it at _CST/P_LVL +- * detection phase, to work cleanly with logical CPU hotplug. +- */ +- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && +- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) +- cx = &pr->power.states[ACPI_STATE_C1]; +-#endif +- +- /* +- * Sleep: +- * ------ +- * Invoke the current Cx state to put the processor to sleep. +- */ +- if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { +- current_thread_info()->status &= ~TS_POLLING; +- /* +- * TS_POLLING-cleared state must be visible before we +- * test NEED_RESCHED: +- */ +- smp_mb(); +- if (need_resched()) { +- current_thread_info()->status |= TS_POLLING; +- local_irq_enable(); +- return; +- } +- } +- +- switch (cx->type) { +- +- case ACPI_STATE_C1: +- /* +- * Invoke C1. +- * Use the appropriate idle routine, the one that would +- * be used without acpi C-states. +- */ +- if (pm_idle_save) +- pm_idle_save(); +- else +- acpi_safe_halt(); +- +- /* +- * TBD: Can't get time duration while in C1, as resumes +- * go to an ISR rather than here. Need to instrument +- * base interrupt handler. +- */ +- sleep_ticks = 0xFFFFFFFF; +- break; +- +- case ACPI_STATE_C2: +- /* Get start time (ticks) */ +- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); +- /* Invoke C2 */ +- acpi_state_timer_broadcast(pr, cx, 1); +- acpi_cstate_enter(cx); +- /* Get end time (ticks) */ +- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +- +-#ifdef CONFIG_GENERIC_TIME +- /* TSC halts in C2, so notify users */ +- mark_tsc_unstable("possible TSC halt in C2"); +-#endif +- /* Re-enable interrupts */ +- local_irq_enable(); +- current_thread_info()->status |= TS_POLLING; +- /* Compute time (ticks) that we were actually asleep */ +- sleep_ticks = +- ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; +- acpi_state_timer_broadcast(pr, cx, 0); +- break; +- +- case ACPI_STATE_C3: +- +- if (pr->flags.bm_check) { +- if (atomic_inc_return(&c3_cpu_count) == +- num_online_cpus()) { +- /* +- * All CPUs are trying to go to C3 +- * Disable bus master arbitration +- */ +- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); +- } +- } else { +- /* SMP with no shared cache... Invalidate cache */ +- ACPI_FLUSH_CPU_CACHE(); +- } +- +- /* Get start time (ticks) */ +- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); +- /* Invoke C3 */ +- acpi_state_timer_broadcast(pr, cx, 1); +- acpi_cstate_enter(cx); +- /* Get end time (ticks) */ +- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +- if (pr->flags.bm_check) { +- /* Enable bus master arbitration */ +- atomic_dec(&c3_cpu_count); +- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); +- } +- +-#ifdef CONFIG_GENERIC_TIME +- /* TSC halts in C3, so notify users */ +- mark_tsc_unstable("TSC halts in C3"); +-#endif +- /* Re-enable interrupts */ +- local_irq_enable(); +- current_thread_info()->status |= TS_POLLING; +- /* Compute time (ticks) that we were actually asleep */ +- sleep_ticks = +- ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; +- acpi_state_timer_broadcast(pr, cx, 0); +- break; +- +- default: +- local_irq_enable(); +- return; +- } +- cx->usage++; +- if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0)) +- cx->time += sleep_ticks; +- +- next_state = pr->power.state; +- +-#ifdef CONFIG_HOTPLUG_CPU +- /* Don't do promotion/demotion */ +- if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && +- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { +- next_state = cx; +- goto end; +- } +-#endif +- +- /* +- * Promotion? +- * ---------- +- * Track the number of longs (time asleep is greater than threshold) +- * and promote when the count threshold is reached. Note that bus +- * mastering activity may prevent promotions. +- * Do not promote above max_cstate. +- */ +- if (cx->promotion.state && +- ((cx->promotion.state - pr->power.states) <= max_cstate)) { +- if (sleep_ticks > cx->promotion.threshold.ticks && +- cx->promotion.state->latency <= system_latency_constraint()) { +- cx->promotion.count++; +- cx->demotion.count = 0; +- if (cx->promotion.count >= +- cx->promotion.threshold.count) { +- if (pr->flags.bm_check) { +- if (! +- (pr->power.bm_activity & cx-> +- promotion.threshold.bm)) { +- next_state = +- cx->promotion.state; +- goto end; +- } +- } else { +- next_state = cx->promotion.state; +- goto end; +- } +- } +- } +- } +- +- /* +- * Demotion? +- * --------- +- * Track the number of shorts (time asleep is less than time threshold) +- * and demote when the usage threshold is reached. +- */ +- if (cx->demotion.state) { +- if (sleep_ticks < cx->demotion.threshold.ticks) { +- cx->demotion.count++; +- cx->promotion.count = 0; +- if (cx->demotion.count >= cx->demotion.threshold.count) { +- next_state = cx->demotion.state; +- goto end; +- } +- } +- } +- +- end: +- /* +- * Demote if current state exceeds max_cstate +- * or if the latency of the current state is unacceptable +- */ +- if ((pr->power.state - pr->power.states) > max_cstate || +- pr->power.state->latency > system_latency_constraint()) { +- if (cx->demotion.state) +- next_state = cx->demotion.state; +- } +- +- /* +- * New Cx State? +- * ------------- +- * If we're going to start using a new Cx state we must clean up +- * from the previous and prepare to use the new. +- */ +- if (next_state != pr->power.state) +- acpi_processor_power_activate(pr, next_state); +-} +- +-static int acpi_processor_set_power_policy(struct acpi_processor *pr) +-{ +- unsigned int i; +- unsigned int state_is_set = 0; +- struct acpi_processor_cx *lower = NULL; +- struct acpi_processor_cx *higher = NULL; +- struct acpi_processor_cx *cx; +- +- +- if (!pr) +- return -EINVAL; +- +- /* +- * This function sets the default Cx state policy (OS idle handler). +- * Our scheme is to promote quickly to C2 but more conservatively +- * to C3. We're favoring C2 for its characteristics of low latency +- * (quick response), good power savings, and ability to allow bus +- * mastering activity. Note that the Cx state policy is completely +- * customizable and can be altered dynamically. +- */ +- +- /* startup state */ +- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { +- cx = &pr->power.states[i]; +- if (!cx->valid) +- continue; +- +- if (!state_is_set) +- pr->power.state = cx; +- state_is_set++; +- break; +- } +- +- if (!state_is_set) +- return -ENODEV; +- +- /* demotion */ +- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { +- cx = &pr->power.states[i]; +- if (!cx->valid) +- continue; +- +- if (lower) { +- cx->demotion.state = lower; +- cx->demotion.threshold.ticks = cx->latency_ticks; +- cx->demotion.threshold.count = 1; +- if (cx->type == ACPI_STATE_C3) +- cx->demotion.threshold.bm = bm_history; +- } +- +- lower = cx; +- } +- +- /* promotion */ +- for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) { +- cx = &pr->power.states[i]; +- if (!cx->valid) +- continue; +- +- if (higher) { +- cx->promotion.state = higher; +- cx->promotion.threshold.ticks = cx->latency_ticks; +- if (cx->type >= ACPI_STATE_C2) +- cx->promotion.threshold.count = 4; +- else +- cx->promotion.threshold.count = 10; +- if (higher->type == ACPI_STATE_C3) +- cx->promotion.threshold.bm = bm_history; +- } +- +- higher = cx; +- } +- +- return 0; +-} +- + static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) + { + +@@ -929,7 +474,7 @@ + * Normalize the C2 latency to expidite policy + */ + cx->valid = 1; +- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); ++ cx->latency_ticks = cx->latency; + + return; + } +@@ -1003,7 +548,7 @@ + * use this in our C3 policy + */ + cx->valid = 1; +- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); ++ cx->latency_ticks = cx->latency; + + return; + } +@@ -1069,18 +614,6 @@ + pr->power.count = acpi_processor_power_verify(pr); + + /* +- * Set Default Policy +- * ------------------ +- * Now that we know which states are supported, set the default +- * policy. Note that this policy can be changed dynamically +- * (e.g. encourage deeper sleeps to conserve battery life when +- * not on AC). +- */ +- result = acpi_processor_set_power_policy(pr); +- if (result) +- return result; +- +- /* + * if one state of type C2 or C3 is available, mark this + * CPU as being "idle manageable" + */ +@@ -1097,9 +630,6 @@ + + int acpi_processor_cst_has_changed(struct acpi_processor *pr) + { +- int result = 0; +- +- + if (!pr) + return -EINVAL; + +@@ -1110,16 +640,9 @@ + if (!pr->flags.power_setup_done) + return -ENODEV; + +- /* Fall back to the default idle loop */ +- pm_idle = pm_idle_save; +- synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ +- +- pr->flags.power = 0; +- result = acpi_processor_get_power_info(pr); +- if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) +- pm_idle = acpi_processor_idle; +- +- return result; ++ acpi_processor_get_power_info(pr); ++ return cpuidle_force_redetect(per_cpu(cpuidle_devices, pr->id), ++ &acpi_idle_driver); + } + + /* proc interface */ +@@ -1205,30 +728,6 @@ + .release = single_release, + }; + +-#ifdef CONFIG_SMP +-static void smp_callback(void *v) +-{ +- /* we already woke the CPU up, nothing more to do */ +-} +- +-/* +- * This function gets called when a part of the kernel has a new latency +- * requirement. This means we need to get all processors out of their C-state, +- * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that +- * wakes them all right up. +- */ +-static int acpi_processor_latency_notify(struct notifier_block *b, +- unsigned long l, void *v) +-{ +- smp_call_function(smp_callback, NULL, 0, 1); +- return NOTIFY_OK; +-} +- +-static struct notifier_block acpi_processor_latency_notifier = { +- .notifier_call = acpi_processor_latency_notify, +-}; +-#endif +- + int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, + struct acpi_device *device) + { +@@ -1245,9 +744,6 @@ + "ACPI: processor limited to max C-state %d\n", + max_cstate); + first_run++; +-#ifdef CONFIG_SMP +- register_latency_notifier(&acpi_processor_latency_notifier); +-#endif + } + + if (!pr) +@@ -1264,6 +760,7 @@ + + acpi_processor_get_power_info(pr); + ++ + /* + * Install the idle handler if processor power management is supported. + * Note that we use previously set idle handler will be used on +@@ -1276,11 +773,6 @@ + printk(" C%d[C%d]", i, + pr->power.states[i].type); + printk(")\n"); +- +- if (pr->id == 0) { +- pm_idle_save = pm_idle; +- pm_idle = acpi_processor_idle; +- } + } + + /* 'power' [R] */ +@@ -1308,21 +800,357 @@ + if (acpi_device_dir(device)) + remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, + acpi_device_dir(device)); ++ return 0; ++} + +- /* Unregister the idle handler when processor #0 is removed. */ +- if (pr->id == 0) { +- pm_idle = pm_idle_save; ++/** ++ * ticks_elapsed - a helper function that determines how many ticks (in US) ++ * have elapsed between two PM Timer timestamps ++ * @t1: the start time ++ * @t2: the end time ++ */ ++static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) ++{ ++ if (t2 >= t1) ++ return PM_TIMER_TICKS_TO_US(t2 - t1); ++ else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) ++ return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); ++ else ++ return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); ++} + +- /* +- * We are about to unload the current idle thread pm callback +- * (pm_idle), Wait for all processors to update cached/local +- * copies of pm_idle before proceeding. +- */ +- cpu_idle_wait(); +-#ifdef CONFIG_SMP +- unregister_latency_notifier(&acpi_processor_latency_notifier); ++static inline u32 ticks_elapsed(u32 t1, u32 t2) ++{ ++ if (t2 >= t1) ++ return (t2 - t1); ++ else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) ++ return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); ++ else ++ return ((0xFFFFFFFF - t1) + t2); ++} ++ ++/** ++ * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state ++ * @pr: the processor ++ * @target: the new target state ++ */ ++static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, ++ struct acpi_processor_cx *target) ++{ ++ if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); ++ pr->flags.bm_rld_set = 0; ++ } ++ ++ if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); ++ pr->flags.bm_rld_set = 1; ++ } ++} ++ ++/** ++ * acpi_idle_do_entry - a helper function that does C2 and C3 type entry ++ * @cx: cstate data ++ */ ++static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) ++{ ++ /* ++ * We have irqs disabled here, so stop latency tracing ++ * at this point and restart it after we return: ++ */ ++ stop_critical_timing(); ++ ++ if (cx->space_id == ACPI_CSTATE_FFH) { ++ /* Call into architectural FFH based C-state */ ++ acpi_processor_ffh_cstate_enter(cx); ++ } else { ++ int unused; ++ /* IO port based C-state */ ++ inb(cx->address); ++ /* Dummy wait op - must do something useless after P_LVL2 read ++ because chipsets cannot guarantee that STPCLK# signal ++ gets asserted in time to freeze execution properly. */ ++ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ } ++ ++ touch_critical_timing(); ++} ++ ++/** ++ * acpi_idle_enter_c1 - enters an ACPI C1 state-type ++ * @dev: the target CPU ++ * @state: the state data ++ * ++ * This is equivalent to the HALT instruction. ++ */ ++static int acpi_idle_enter_c1(struct cpuidle_device *dev, ++ struct cpuidle_state *state) ++{ ++ struct acpi_processor *pr; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ pr = processors[smp_processor_id()]; ++ ++ if (unlikely(!pr)) ++ return 0; ++ ++ if (pr->flags.bm_check) ++ acpi_idle_update_bm_rld(pr, cx); ++ ++ current_thread_info()->status &= ~TS_POLLING; ++ /* ++ * TS_POLLING-cleared state must be visible before we test ++ * NEED_RESCHED: ++ */ ++ smp_mb(); ++ if (!need_resched() || !need_resched_delayed()) ++ safe_halt(); ++ current_thread_info()->status |= TS_POLLING; ++ ++ cx->usage++; ++ ++ return 0; ++} ++ ++/** ++ * acpi_idle_enter_c2 - enters an ACPI C2 state-type ++ * @dev: the target CPU ++ * @state: the state data ++ */ ++static int acpi_idle_enter_c2(struct cpuidle_device *dev, ++ struct cpuidle_state *state) ++{ ++ struct acpi_processor *pr; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ u32 t1, t2; ++ pr = processors[smp_processor_id()]; ++ ++ if (unlikely(!pr)) ++ return 0; ++ ++ if (pr->flags.bm_check) ++ acpi_idle_update_bm_rld(pr, cx); ++ ++ local_irq_disable(); ++ current_thread_info()->status &= ~TS_POLLING; ++ /* ++ * TS_POLLING-cleared state must be visible before we test ++ * NEED_RESCHED: ++ */ ++ smp_mb(); ++ ++ if (unlikely(need_resched() || need_resched_delayed())) { ++ current_thread_info()->status |= TS_POLLING; ++ local_irq_enable(); ++ return 0; ++ } ++ ++ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ acpi_state_timer_broadcast(pr, cx, 1); ++ acpi_idle_do_entry(cx); ++ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ ++#ifdef CONFIG_GENERIC_TIME ++ /* TSC halts in C2, so notify users */ ++ mark_tsc_unstable("possible TSC halt in C2"); + #endif ++ ++ local_irq_enable(); ++ current_thread_info()->status |= TS_POLLING; ++ ++ cx->usage++; ++ ++ acpi_state_timer_broadcast(pr, cx, 0); ++ cx->time += ticks_elapsed(t1, t2); ++ return ticks_elapsed_in_us(t1, t2); ++} ++ ++static int c3_cpu_count; ++static DEFINE_RAW_SPINLOCK(c3_lock); ++ ++/** ++ * acpi_idle_enter_c3 - enters an ACPI C3 state-type ++ * @dev: the target CPU ++ * @state: the state data ++ * ++ * Similar to C2 entry, except special bus master handling is needed. ++ */ ++static int acpi_idle_enter_c3(struct cpuidle_device *dev, ++ struct cpuidle_state *state) ++{ ++ struct acpi_processor *pr; ++ struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ++ u32 t1, t2; ++ pr = processors[smp_processor_id()]; ++ ++ if (unlikely(!pr)) ++ return 0; ++ ++ if (pr->flags.bm_check) ++ acpi_idle_update_bm_rld(pr, cx); ++ ++ local_irq_disable(); ++ current_thread_info()->status &= ~TS_POLLING; ++ /* ++ * TS_POLLING-cleared state must be visible before we test ++ * NEED_RESCHED: ++ */ ++ smp_mb(); ++ ++ if (unlikely(need_resched() || need_resched_delayed())) { ++ current_thread_info()->status |= TS_POLLING; ++ local_irq_enable(); ++ return 0; ++ } ++ ++ /* ++ * Must be done before busmaster disable as we might need to ++ * access HPET ! ++ */ ++ acpi_state_timer_broadcast(pr, cx, 1); ++ ++ /* disable bus master */ ++ if (pr->flags.bm_check) { ++ spin_lock(&c3_lock); ++ c3_cpu_count++; ++ if (c3_cpu_count == num_online_cpus()) { ++ /* ++ * All CPUs are trying to go to C3 ++ * Disable bus master arbitration ++ */ ++ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); ++ } ++ spin_unlock(&c3_lock); ++ } else { ++ /* SMP with no shared cache... Invalidate cache */ ++ ACPI_FLUSH_CPU_CACHE(); + } + ++ /* Get start time (ticks) */ ++ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ acpi_idle_do_entry(cx); ++ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ ++ if (pr->flags.bm_check) { ++ spin_lock(&c3_lock); ++ /* Enable bus master arbitration */ ++ if (c3_cpu_count == num_online_cpus()) ++ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); ++ c3_cpu_count--; ++ spin_unlock(&c3_lock); ++ } ++ ++#ifdef CONFIG_GENERIC_TIME ++ /* TSC halts in C3, so notify users */ ++ mark_tsc_unstable("TSC halts in C3"); ++#endif ++ ++ local_irq_enable(); ++ current_thread_info()->status |= TS_POLLING; ++ ++ cx->usage++; ++ ++ acpi_state_timer_broadcast(pr, cx, 0); ++ cx->time += ticks_elapsed(t1, t2); ++ return ticks_elapsed_in_us(t1, t2); ++} ++ ++/** ++ * acpi_idle_bm_check - checks if bus master activity was detected ++ */ ++static int acpi_idle_bm_check(void) ++{ ++ u32 bm_status = 0; ++ ++ acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); ++ if (bm_status) ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); ++ /* ++ * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect ++ * the true state of bus mastering activity; forcing us to ++ * manually check the BMIDEA bit of each IDE channel. ++ */ ++ else if (errata.piix4.bmisx) { ++ if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) ++ || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) ++ bm_status = 1; ++ } ++ return bm_status; ++} ++ ++/** ++ * acpi_idle_init - attaches the driver to a CPU ++ * @dev: the CPU ++ */ ++static int acpi_idle_init(struct cpuidle_device *dev) ++{ ++ int cpu = dev->cpu; ++ int i, count = 0; ++ struct acpi_processor_cx *cx; ++ struct cpuidle_state *state; ++ ++ struct acpi_processor *pr = processors[cpu]; ++ ++ if (!pr->flags.power_setup_done) ++ return -EINVAL; ++ ++ if (pr->flags.power == 0) { ++ return -EINVAL; ++ } ++ ++ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { ++ cx = &pr->power.states[i]; ++ state = &dev->states[count]; ++ ++ if (!cx->valid) ++ continue; ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && ++ !pr->flags.has_cst && ++ !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) ++ continue; ++#endif ++ cpuidle_set_statedata(state, cx); ++ ++ state->exit_latency = cx->latency; ++ state->target_residency = cx->latency * 6; ++ state->power_usage = cx->power; ++ ++ state->flags = 0; ++ switch (cx->type) { ++ case ACPI_STATE_C1: ++ state->flags |= CPUIDLE_FLAG_SHALLOW; ++ state->enter = acpi_idle_enter_c1; ++ break; ++ ++ case ACPI_STATE_C2: ++ state->flags |= CPUIDLE_FLAG_BALANCED; ++ state->flags |= CPUIDLE_FLAG_TIME_VALID; ++ state->enter = acpi_idle_enter_c2; ++ break; ++ ++ case ACPI_STATE_C3: ++ state->flags |= CPUIDLE_FLAG_DEEP; ++ state->flags |= CPUIDLE_FLAG_TIME_VALID; ++ state->flags |= CPUIDLE_FLAG_CHECK_BM; ++ state->enter = acpi_idle_enter_c3; ++ break; ++ } ++ ++ count++; ++ } ++ ++ if (!count) ++ return -EINVAL; ++ ++ dev->state_count = count; + return 0; + } ++ ++struct cpuidle_driver acpi_idle_driver = { ++ .name = "acpi_idle", ++ .init = acpi_idle_init, ++ .redetect = acpi_idle_init, ++ .bm_check = acpi_idle_bm_check, ++ .owner = THIS_MODULE, ++}; +diff -Nur custom-source-rt.orig/drivers/acpi/utilities/utmutex.c custom-source-rt/drivers/acpi/utilities/utmutex.c +--- custom-source-rt.orig/drivers/acpi/utilities/utmutex.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/acpi/utilities/utmutex.c 2007-10-02 17:31:08.000000000 +0000 +@@ -116,7 +116,7 @@ + /* Delete the spinlocks */ + + acpi_os_delete_lock(acpi_gbl_gpe_lock); +- acpi_os_delete_lock(acpi_gbl_hardware_lock); ++// acpi_os_delete_lock(acpi_gbl_hardware_lock); + return_VOID; + } + +diff -Nur custom-source-rt.orig/drivers/base/power/resume.c custom-source-rt/drivers/base/power/resume.c +--- custom-source-rt.orig/drivers/base/power/resume.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/base/power/resume.c 2007-10-02 17:31:08.000000000 +0000 +@@ -9,6 +9,7 @@ + */ + + #include ++#include + #include + #include "../base.h" + #include "power.h" +diff -Nur custom-source-rt.orig/drivers/block/floppy.c custom-source-rt/drivers/block/floppy.c +--- custom-source-rt.orig/drivers/block/floppy.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/block/floppy.c 2007-10-02 17:31:08.000000000 +0000 +@@ -4157,6 +4157,28 @@ + complete(&device_release); + } + ++static int floppy_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ floppy_release_irq_and_dma(); ++ ++ return 0; ++} ++ ++static int floppy_resume(struct platform_device *dev) ++{ ++ floppy_grab_irq_and_dma(); ++ ++ return 0; ++} ++ ++static struct platform_driver floppy_driver = { ++ .suspend = floppy_suspend, ++ .resume = floppy_resume, ++ .driver = { ++ .name = "floppy", ++ }, ++}; ++ + static struct platform_device floppy_device[N_DRIVE]; + + static struct kobject *floppy_find(dev_t dev, int *part, void *data) +@@ -4205,10 +4227,14 @@ + if (err) + goto out_put_disk; + ++ err = platform_driver_register(&floppy_driver); ++ if (err) ++ goto out_unreg_blkdev; ++ + floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); + if (!floppy_queue) { + err = -ENOMEM; +- goto out_unreg_blkdev; ++ goto out_unreg_driver; + } + blk_queue_max_sectors(floppy_queue, 64); + +@@ -4357,6 +4383,8 @@ + out_unreg_region: + blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); + blk_cleanup_queue(floppy_queue); ++out_unreg_driver: ++ platform_driver_unregister(&floppy_driver); + out_unreg_blkdev: + unregister_blkdev(FLOPPY_MAJOR, "fd"); + out_put_disk: +@@ -4548,6 +4576,7 @@ + init_completion(&device_release); + blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); + unregister_blkdev(FLOPPY_MAJOR, "fd"); ++ platform_driver_unregister(&floppy_driver); + + for (drive = 0; drive < N_DRIVE; drive++) { + del_timer_sync(&motor_off_timer[drive]); +diff -Nur custom-source-rt.orig/drivers/block/paride/pseudo.h custom-source-rt/drivers/block/paride/pseudo.h +--- custom-source-rt.orig/drivers/block/paride/pseudo.h 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/block/paride/pseudo.h 2007-10-02 17:31:08.000000000 +0000 +@@ -43,7 +43,7 @@ + static int ps_tq_active = 0; + static int ps_nice = 0; + +-static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); ++static __attribute__((unused)) DEFINE_SPINLOCK(ps_spinlock); + + static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int); + +diff -Nur custom-source-rt.orig/drivers/cdrom/sjcd.c custom-source-rt/drivers/cdrom/sjcd.c +--- custom-source-rt.orig/drivers/cdrom/sjcd.c 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/cdrom/sjcd.c 2007-10-02 17:31:08.000000000 +0000 +@@ -69,6 +69,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1709,12 +1710,11 @@ + printk(KERN_INFO "SJCD: Resetting: "); + sjcd_send_cmd(SCMD_RESET); + for (i = 1000; i > 0 && !sjcd_status_valid; --i) { +- unsigned long timer; +- + /* + * Wait 10ms approx. + */ +- for (timer = jiffies; time_before_eq(jiffies, timer);); ++ msleep(10); ++ + if ((i % 100) == 0) + printk("."); + (void) sjcd_check_status(); +diff -Nur custom-source-rt.orig/drivers/char/Kconfig custom-source-rt/drivers/char/Kconfig +--- custom-source-rt.orig/drivers/char/Kconfig 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/char/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -791,6 +791,46 @@ + To compile this driver as a module, choose M here: the + module will be called rtc. + ++config RTC_HISTOGRAM ++ bool "Real Time Clock Histogram Support" ++ default n ++ depends on RTC ++ ---help--- ++ If you say Y here then the kernel will track the delivery and ++ wakeup latency of /dev/rtc using tasks and will report a ++ histogram to the kernel log when the application closes /dev/rtc. ++ ++config BLOCKER ++ tristate "Priority Inheritance Debugging (Blocker) Device Support" ++ depends on X86 ++ default y ++ ---help--- ++ If you say Y here then a device will be created that the userspace ++ pi_test suite uses to test and measure kernel locking primitives. ++ ++config LPPTEST ++ tristate "Parallel Port Based Latency Measurement Device" ++ depends on !PARPORT && X86 ++ default y ++ ---help--- ++ If you say Y here then a device will be created that the userspace ++ testlpp utility uses to measure IRQ latencies of a target system ++ from an independent measurement system. ++ ++ NOTE: this code assumes x86 PCs and that the parallel port is ++ bidirectional and is on IRQ 7. ++ ++ to use the device, both the target and the source system needs to ++ run a kernel with CONFIG_LPPTEST enabled. To measure latencies, ++ use the scripts/testlpp utility in your kernel source directory, ++ and run it (as root) on the source system - it will start printing ++ out the latencies it took to get a response from the target system: ++ ++ Latency of response: 12.2 usecs (121265 cycles) ++ ++ then generate various workloads on the target system to see how ++ (worst-case-) latencies are impacted. ++ + config SGI_DS1286 + tristate "SGI DS1286 RTC support" + depends on SGI_IP22 +@@ -1075,6 +1115,24 @@ + /sys/devices/platform/telco_clock, with a number of files for + controlling the behavior of this hardware. + ++config RMEM ++ tristate "Access to physical memory via /dev/rmem" ++ default m ++ help ++ The /dev/mem device only allows mmap() memory available to ++ I/O mapped memory; it does not allow access to "real" ++ physical memory. The /dev/rmem device is a hack which does ++ allow access to physical memory. We use this instead of ++ patching /dev/mem because we don't expect this functionality ++ to ever be accepted into mainline. ++ ++config ALLOC_RTSJ_MEM ++ tristate "RTSJ-specific hack to reserve memory" ++ default m ++ help ++ The RTSJ TCK conformance test requires reserving some physical ++ memory for testing /dev/rmem. ++ + config DEVPORT + bool + depends on !M68K +diff -Nur custom-source-rt.orig/drivers/char/Makefile custom-source-rt/drivers/char/Makefile +--- custom-source-rt.orig/drivers/char/Makefile 2007-08-21 04:00:18.000000000 +0000 ++++ custom-source-rt/drivers/char/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -94,6 +94,10 @@ + obj-$(CONFIG_GPIO_TB0219) += tb0219.o + obj-$(CONFIG_TELCLOCK) += tlclk.o + ++obj-$(CONFIG_BLOCKER) += blocker.o ++obj-$(CONFIG_LPPTEST) += lpptest.o ++obj-$(CONFIG_RMEM) += rmem.o ++ + obj-$(CONFIG_WATCHDOG) += watchdog/ + obj-$(CONFIG_MWAVE) += mwave/ + obj-$(CONFIG_AGP) += agp/ +@@ -104,6 +108,8 @@ + obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o + obj-$(CONFIG_TCG_TPM) += tpm/ + ++obj-$(CONFIG_ALLOC_RTSJ_MEM) += alloc_rtsj_mem.o ++ + # Files generated that shall be removed upon make clean + clean-files := consolemap_deftbl.c defkeymap.c + +diff -Nur custom-source-rt.orig/drivers/char/alloc_rtsj_mem.c custom-source-rt/drivers/char/alloc_rtsj_mem.c +--- custom-source-rt.orig/drivers/char/alloc_rtsj_mem.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/char/alloc_rtsj_mem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,88 @@ ++/* ++ * alloc_rtsj_mem.c -- Hack to allocate some memory ++ * ++ * Copyright (C) 2005 by Theodore Ts'o ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++MODULE_AUTHOR("Theodore Tso"); ++MODULE_DESCRIPTION("RTSJ alloc memory"); ++MODULE_LICENSE("GPL"); ++ ++static void *mem = 0; ++int size = 0, addr = 0; ++ ++module_param(size, int, 0444); ++module_param(addr, int, 0444); ++ ++static void __exit shutdown_module(void) ++{ ++ kfree(mem); ++} ++ ++#ifndef MODULE ++void __init alloc_rtsj_mem_early_setup(void) ++{ ++ if (size > PAGE_SIZE*2) { ++ mem = alloc_bootmem(size); ++ if (mem) { ++ printk(KERN_INFO "alloc_rtsj_mem: got %d bytes " ++ "using alloc_bootmem\n", size); ++ } else { ++ printk(KERN_INFO "alloc_rtsj_mem: failed to " ++ "get %d bytes from alloc_bootmem\n", size); ++ } ++ } ++} ++#endif ++ ++static int __init startup_module(void) ++{ ++ static char test_string[] = "The BOFH: Servicing users the way the " ++ "military\n\tservices targets for 15 years.\n"; ++ ++ if (!size) ++ return 0; ++ ++ if (!mem) { ++ mem = kmalloc(size, GFP_KERNEL); ++ if (mem) { ++ printk(KERN_INFO "alloc_rtsj_mem: got %d bytes " ++ "using kmalloc\n", size); ++ } else { ++ printk(KERN_ERR "alloc_rtsj_mem: failed to get " ++ "%d bytes using kmalloc\n", size); ++ return -ENOMEM; ++ } ++ } ++ memcpy(mem, test_string, min(sizeof(test_string), (size_t) size)); ++ addr = virt_to_phys(mem); ++ return 0; ++} ++ ++module_init(startup_module); ++module_exit(shutdown_module); ++ +diff -Nur custom-source-rt.orig/drivers/char/blocker.c custom-source-rt/drivers/char/blocker.c +--- custom-source-rt.orig/drivers/char/blocker.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/char/blocker.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,107 @@ ++/* ++ * priority inheritance testing device ++ */ ++ ++#include ++#include ++ ++#define BLOCKER_MINOR 221 ++ ++#define BLOCK_IOCTL 4245 ++#define BLOCK_SET_DEPTH 4246 ++ ++#define BLOCKER_MAX_LOCK_DEPTH 10 ++ ++void loop(int loops) ++{ ++ int i; ++ ++ for (i = 0; i < loops; i++) ++ get_cycles(); ++} ++ ++static spinlock_t blocker_lock[BLOCKER_MAX_LOCK_DEPTH]; ++ ++static unsigned int lock_depth = 1; ++ ++void do_the_lock_and_loop(unsigned int args) ++{ ++ int i, max; ++ ++ if (rt_task(current)) ++ max = lock_depth; ++ else if (lock_depth > 1) ++ max = (current->pid % lock_depth) + 1; ++ else ++ max = 1; ++ ++ /* Always lock from the top down */ ++ for (i = max-1; i >= 0; i--) ++ spin_lock(&blocker_lock[i]); ++ loop(args); ++ for (i = 0; i < max; i++) ++ spin_unlock(&blocker_lock[i]); ++} ++ ++static int blocker_open(struct inode *in, struct file *file) ++{ ++ printk(KERN_INFO "blocker_open called\n"); ++ ++ return 0; ++} ++ ++static long blocker_ioctl(struct file *file, ++ unsigned int cmd, unsigned long args) ++{ ++ switch(cmd) { ++ case BLOCK_IOCTL: ++ do_the_lock_and_loop(args); ++ return 0; ++ case BLOCK_SET_DEPTH: ++ if (args >= BLOCKER_MAX_LOCK_DEPTH) ++ return -EINVAL; ++ lock_depth = args; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static struct file_operations blocker_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .unlocked_ioctl = blocker_ioctl, ++ .open = blocker_open, ++}; ++ ++static struct miscdevice blocker_dev = ++{ ++ BLOCKER_MINOR, ++ "blocker", ++ &blocker_fops ++}; ++ ++static int __init blocker_init(void) ++{ ++ int i; ++ ++ if (misc_register(&blocker_dev)) ++ return -ENODEV; ++ ++ for (i = 0; i < BLOCKER_MAX_LOCK_DEPTH; i++) ++ spin_lock_init(blocker_lock + i); ++ ++ return 0; ++} ++ ++void __exit blocker_exit(void) ++{ ++ printk(KERN_INFO "blocker device uninstalled\n"); ++ misc_deregister(&blocker_dev); ++} ++ ++module_init(blocker_init); ++module_exit(blocker_exit); ++ ++MODULE_LICENSE("GPL"); ++ +diff -Nur custom-source-rt.orig/drivers/char/lpptest.c custom-source-rt/drivers/char/lpptest.c +--- custom-source-rt.orig/drivers/char/lpptest.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/char/lpptest.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,178 @@ ++/* ++ * /dev/lpptest device: test IRQ handling latencies over parallel port ++ * ++ * Copyright (C) 2005 Thomas Gleixner, Ingo Molnar ++ * ++ * licensed under the GPL ++ * ++ * You need to have CONFIG_PARPORT disabled for this device, it is a ++ * completely self-contained device that assumes sole ownership of the ++ * parallel port. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * API wrappers so that the code can be shared with the -rt tree: ++ */ ++#ifndef local_irq_disable ++# define local_irq_disable local_irq_disable ++# define local_irq_enable local_irq_enable ++#endif ++ ++#ifndef IRQ_NODELAY ++# define IRQ_NODELAY 0 ++# define IRQF_NODELAY 0 ++#endif ++ ++/* ++ * Driver: ++ */ ++#define LPPTEST_CHAR_MAJOR 245 ++#define LPPTEST_DEVICE_NAME "lpptest" ++ ++#define LPPTEST_IRQ 7 ++ ++#define LPPTEST_TEST _IOR (LPPTEST_CHAR_MAJOR, 1, unsigned long long) ++#define LPPTEST_DISABLE _IOR (LPPTEST_CHAR_MAJOR, 2, unsigned long long) ++#define LPPTEST_ENABLE _IOR (LPPTEST_CHAR_MAJOR, 3, unsigned long long) ++ ++static char dev_id[] = "lpptest"; ++ ++#define INIT_PORT() outb(0x04, 0x37a) ++#define ENABLE_IRQ() outb(0x10, 0x37a) ++#define DISABLE_IRQ() outb(0, 0x37a) ++ ++static unsigned char out = 0x5a; ++ ++/** ++ * Interrupt handler. Flip a bit in the reply. ++ */ ++static int lpptest_irq (int irq, void *dev_id) ++{ ++ out ^= 0xff; ++ outb(out, 0x378); ++ ++ return IRQ_HANDLED; ++} ++ ++static cycles_t test_response(void) ++{ ++ cycles_t now, end; ++ unsigned char in; ++ int timeout = 0; ++ ++ local_irq_disable(); ++ in = inb(0x379); ++ inb(0x378); ++ outb(0x08, 0x378); ++ now = get_cycles(); ++ while(1) { ++ if (inb(0x379) != in) ++ break; ++ if (timeout++ > 1000000) { ++ outb(0x00, 0x378); ++ local_irq_enable(); ++ ++ return 0; ++ } ++ } ++ end = get_cycles(); ++ outb(0x00, 0x378); ++ local_irq_enable(); ++ ++ return end - now; ++} ++ ++static int lpptest_open(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++static int lpptest_close(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++int lpptest_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) ++{ ++ int retval = 0; ++ ++ switch (ioctl_num) { ++ ++ case LPPTEST_DISABLE: ++ DISABLE_IRQ(); ++ break; ++ ++ case LPPTEST_ENABLE: ++ ENABLE_IRQ(); ++ break; ++ ++ case LPPTEST_TEST: { ++ ++ cycles_t diff = test_response(); ++ if (copy_to_user((void *)ioctl_param, (void*) &diff, sizeof(diff))) ++ goto errcpy; ++ break; ++ } ++ default: retval = -EINVAL; ++ } ++ ++ return retval; ++ ++ errcpy: ++ return -EFAULT; ++} ++ ++static struct file_operations lpptest_dev_fops = { ++ .ioctl = lpptest_ioctl, ++ .open = lpptest_open, ++ .release = lpptest_close, ++}; ++ ++static int __init lpptest_init (void) ++{ ++ if (register_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME, &lpptest_dev_fops)) ++ { ++ printk(KERN_NOTICE "Can't allocate major number %d for lpptest.\n", ++ LPPTEST_CHAR_MAJOR); ++ return -EAGAIN; ++ } ++ ++ if (request_irq (LPPTEST_IRQ, lpptest_irq, 0, "lpptest", dev_id)) { ++ printk (KERN_WARNING "lpptest: irq %d in use. Unload parport module!\n", LPPTEST_IRQ); ++ unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); ++ return -EAGAIN; ++ } ++ irq_desc[LPPTEST_IRQ].status |= IRQ_NODELAY; ++ irq_desc[LPPTEST_IRQ].action->flags |= IRQF_NODELAY | IRQF_DISABLED; ++ ++ INIT_PORT(); ++ ENABLE_IRQ(); ++ ++ return 0; ++} ++module_init (lpptest_init); ++ ++static void __exit lpptest_exit (void) ++{ ++ DISABLE_IRQ(); ++ ++ free_irq(LPPTEST_IRQ, dev_id); ++ unregister_chrdev(LPPTEST_CHAR_MAJOR, LPPTEST_DEVICE_NAME); ++} ++module_exit (lpptest_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("lpp test module"); ++ +diff -Nur custom-source-rt.orig/drivers/char/random.c custom-source-rt/drivers/char/random.c +--- custom-source-rt.orig/drivers/char/random.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/char/random.c 2007-10-02 17:31:08.000000000 +0000 +@@ -580,8 +580,11 @@ + preempt_disable(); + /* if over the trickle threshold, use only 1 in 4096 samples */ + if (input_pool.entropy_count > trickle_thresh && +- (__get_cpu_var(trickle_count)++ & 0xfff)) +- goto out; ++ (__get_cpu_var(trickle_count)++ & 0xfff)) { ++ preempt_enable(); ++ return; ++ } ++ preempt_enable(); + + sample.jiffies = jiffies; + sample.cycles = get_cycles(); +@@ -626,9 +629,6 @@ + + if(input_pool.entropy_count >= random_read_wakeup_thresh) + wake_up_interruptible(&random_read_wait); +- +-out: +- preempt_enable(); + } + + void add_input_randomness(unsigned int type, unsigned int code, +diff -Nur custom-source-rt.orig/drivers/char/rmem.c custom-source-rt/drivers/char/rmem.c +--- custom-source-rt.orig/drivers/char/rmem.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/char/rmem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,134 @@ ++/* ++ * Rmem - REALLY simple memory mapping demonstration. ++ * ++ * Copyright (C) 2005 by Theodore Ts'o ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int rmem_major = 0; ++module_param(rmem_major, int, 0444); ++ ++static struct class *rmem_class; ++ ++MODULE_AUTHOR("Theodore Ts'o"); ++MODULE_LICENSE("GPL"); ++ ++struct page *rmem_vma_nopage(struct vm_area_struct *vma, ++ unsigned long address, int *type) ++{ ++ struct page *pageptr; ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ unsigned long physaddr = address - vma->vm_start + offset; ++ unsigned long pageframe = physaddr >> PAGE_SHIFT; ++ ++ if (!pfn_valid(pageframe)) ++ return NOPAGE_SIGBUS; ++ pageptr = pfn_to_page(pageframe); ++ get_page(pageptr); ++ if (type) ++ *type = VM_FAULT_MINOR; ++ return pageptr; ++} ++ ++static struct vm_operations_struct rmem_nopage_vm_ops = { ++ .nopage = rmem_vma_nopage, ++}; ++ ++static int rmem_nopage_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC)) ++ vma->vm_flags |= VM_IO; ++ vma->vm_flags |= VM_RESERVED; ++ vma->vm_ops = &rmem_nopage_vm_ops; ++#ifdef TAINT_USER ++ add_taint(TAINT_USER); ++#endif ++ return 0; ++} ++ ++static struct file_operations rmem_nopage_ops = { ++ .owner = THIS_MODULE, ++ .mmap = rmem_nopage_mmap, ++}; ++ ++static struct cdev rmem_cdev = { ++ .kobj = {.name = "rmem", }, ++ .owner = THIS_MODULE, ++}; ++ ++static int __init rmem_init(void) ++{ ++ int result; ++ dev_t dev = MKDEV(rmem_major, 0); ++ ++ /* Figure out our device number. */ ++ if (rmem_major) ++ result = register_chrdev_region(dev, 1, "rmem"); ++ else { ++ result = alloc_chrdev_region(&dev, 0, 1, "rmem"); ++ rmem_major = MAJOR(dev); ++ } ++ if (result < 0) { ++ printk(KERN_WARNING "rmem: unable to get major %d\n", rmem_major); ++ return result; ++ } ++ if (rmem_major == 0) ++ rmem_major = result; ++ ++ cdev_init(&rmem_cdev, &rmem_nopage_ops); ++ result = cdev_add(&rmem_cdev, dev, 1); ++ if (result) { ++ printk (KERN_NOTICE "Error %d adding /dev/rmem", result); ++ kobject_put(&rmem_cdev.kobj); ++ unregister_chrdev_region(dev, 1); ++ return 1; ++ } ++ ++ rmem_class = class_create(THIS_MODULE, "rmem"); ++ class_device_create(rmem_class, NULL, dev, NULL, "rmem"); ++ ++ return 0; ++} ++ ++ ++static void __exit rmem_cleanup(void) ++{ ++ cdev_del(&rmem_cdev); ++ unregister_chrdev_region(MKDEV(rmem_major, 0), 1); ++ class_destroy(rmem_class); ++} ++ ++ ++module_init(rmem_init); ++module_exit(rmem_cleanup); +diff -Nur custom-source-rt.orig/drivers/char/rtc.c custom-source-rt/drivers/char/rtc.c +--- custom-source-rt.orig/drivers/char/rtc.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/char/rtc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -82,7 +82,7 @@ + #include + #include + +-#if defined(__i386__) ++#ifdef CONFIG_X86 + #include + #endif + +@@ -92,11 +92,36 @@ + #ifdef __sparc_v9__ + #include + #endif +- + static unsigned long rtc_port; + static int rtc_irq = PCI_IRQ_NONE; + #endif + ++#ifdef CONFIG_MIPS ++# include ++#endif ++ ++#ifdef CONFIG_RTC_HISTOGRAM ++ ++static cycles_t last_interrupt_time; ++ ++#include ++ ++#define CPU_MHZ (cpu_khz / 1000) ++ ++#define HISTSIZE 10000 ++static int histogram[HISTSIZE]; ++ ++static int rtc_state; ++ ++enum rtc_states { ++ S_STARTUP, /* First round - let the application start */ ++ S_IDLE, /* Waiting for an interrupt */ ++ S_WAITING_FOR_READ, /* Signal delivered. waiting for rtc_read() */ ++ S_READ_MISSED, /* Signal delivered, read() deadline missed */ ++}; ++ ++#endif ++ + #ifdef CONFIG_HPET_RTC_IRQ + #undef RTC_IRQ + #endif +@@ -225,7 +250,146 @@ + return uip; + } + ++#ifndef RTC_IRQ ++# undef CONFIG_RTC_HISTOGRAM ++#endif ++ ++static inline void rtc_open_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ int i; ++ ++ last_interrupt_time = 0; ++ rtc_state = S_STARTUP; ++ rtc_irq_data = 0; ++ ++ for (i = 0; i < HISTSIZE; i++) ++ histogram[i] = 0; ++#endif ++} ++ ++static inline void rtc_wake_event(void) ++{ ++#ifndef CONFIG_RTC_HISTOGRAM ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++#else ++ if (!(rtc_status & RTC_IS_OPEN)) ++ return; ++ ++ switch (rtc_state) { ++ /* Startup */ ++ case S_STARTUP: ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ break; ++ /* Waiting for an interrupt */ ++ case S_IDLE: ++ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ last_interrupt_time = get_cycles(); ++ rtc_state = S_WAITING_FOR_READ; ++ break; ++ ++ /* Signal has been delivered. waiting for rtc_read() */ ++ case S_WAITING_FOR_READ: ++ /* ++ * Well foo. The usermode application didn't ++ * schedule and read in time. ++ */ ++ last_interrupt_time = get_cycles(); ++ rtc_state = S_READ_MISSED; ++ printk("Read missed before next interrupt\n"); ++ break; ++ /* Signal has been delivered, read() deadline was missed */ ++ case S_READ_MISSED: ++ /* ++ * Not much we can do here. We're waiting for the usermode ++ * application to read the rtc ++ */ ++ last_interrupt_time = get_cycles(); ++ break; ++ } ++#endif ++} ++ ++static inline void rtc_read_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ cycles_t now = get_cycles(); ++ ++ switch (rtc_state) { ++ /* Startup */ ++ case S_STARTUP: ++ rtc_state = S_IDLE; ++ break; ++ ++ /* Waiting for an interrupt */ ++ case S_IDLE: ++ printk("bug in rtc_read(): called in state S_IDLE!\n"); ++ break; ++ case S_WAITING_FOR_READ: /* ++ * Signal has been delivered. ++ * waiting for rtc_read() ++ */ ++ /* ++ * Well done ++ */ ++ case S_READ_MISSED: /* ++ * Signal has been delivered, read() ++ * deadline was missed ++ */ ++ /* ++ * So, you finally got here. ++ */ ++ if (!last_interrupt_time) ++ printk("bug in rtc_read(): last_interrupt_time = 0\n"); ++ rtc_state = S_IDLE; ++ { ++ cycles_t latency = now - last_interrupt_time; ++ unsigned long delta; /* Microseconds */ ++ ++ delta = latency; ++ delta /= CPU_MHZ; ++ ++ if (delta > 1000 * 1000) { ++ printk("rtc: eek\n"); ++ } else { ++ unsigned long slot = delta; ++ if (slot >= HISTSIZE) ++ slot = HISTSIZE - 1; ++ histogram[slot]++; ++ if (delta > 2000) ++ printk("wow! That was a " ++ "%ld millisec bump\n", ++ delta / 1000); ++ } ++ } ++ rtc_state = S_IDLE; ++ break; ++ } ++#endif ++} ++ ++static inline void rtc_close_event(void) ++{ ++#ifdef CONFIG_RTC_HISTOGRAM ++ int i = 0; ++ unsigned long total = 0; ++ ++ for (i = 0; i < HISTSIZE; i++) ++ total += histogram[i]; ++ if (!total) ++ return; ++ ++ printk("\nrtc latency histogram of {%s/%d, %lu samples}:\n", ++ current->comm, current->pid, total); ++ for (i = 0; i < HISTSIZE; i++) { ++ if (histogram[i]) ++ printk("%d %d\n", i, histogram[i]); ++ } ++#endif ++} ++ + #ifdef RTC_IRQ ++ + /* + * A very tiny interrupt handler. It runs with IRQF_DISABLED set, + * but there is possibility of conflicting with the set_rtc_mmss() +@@ -269,9 +433,9 @@ + if (rtc_callback) + rtc_callback->func(rtc_callback->private_data); + spin_unlock(&rtc_task_lock); +- wake_up_interruptible(&rtc_wait); + +- kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); ++ rtc_wake_event(); ++ wake_up_interruptible(&rtc_wait); + + return IRQ_HANDLED; + } +@@ -381,6 +545,8 @@ + schedule(); + } while (1); + ++ rtc_read_event(); ++ + if (count == sizeof(unsigned int)) + retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); + else +@@ -613,6 +779,11 @@ + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + ++ /* ++ * Make CMOS date writes nonpreemptible even on PREEMPT_RT. ++ * There's a limit to everything! =B-) ++ */ ++ preempt_disable(); + #ifdef CONFIG_MACH_DECSTATION + CMOS_WRITE(real_yrs, RTC_DEC_YEAR); + #endif +@@ -622,6 +793,7 @@ + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); ++ preempt_enable(); + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); +@@ -720,6 +892,7 @@ + if(rtc_status & RTC_IS_OPEN) + goto out_busy; + ++ rtc_open_event(); + rtc_status |= RTC_IS_OPEN; + + rtc_irq_data = 0; +@@ -775,6 +948,7 @@ + rtc_irq_data = 0; + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq (&rtc_lock); ++ rtc_close_event(); + return 0; + } + +@@ -1159,8 +1333,10 @@ + + spin_unlock_irq(&rtc_lock); + ++#ifndef CONFIG_PREEMPT_RT + if (printk_ratelimit()) + printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); ++#endif + + /* Now we have new data */ + wake_up_interruptible(&rtc_wait); +diff -Nur custom-source-rt.orig/drivers/char/sysrq.c custom-source-rt/drivers/char/sysrq.c +--- custom-source-rt.orig/drivers/char/sysrq.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/char/sysrq.c 2007-10-02 17:31:08.000000000 +0000 +@@ -208,6 +208,22 @@ + .enable_mask = SYSRQ_ENABLE_DUMP, + }; + ++#if defined(__i386__) || defined(__x86_64__) ++ ++static void sysrq_handle_showallregs(int key, struct tty_struct *tty) ++{ ++ nmi_show_all_regs(); ++} ++ ++static struct sysrq_key_op sysrq_showallregs_op = { ++ .handler = sysrq_handle_showallregs, ++ .help_msg = "showalLcpupc", ++ .action_msg = "Show Regs On All CPUs", ++}; ++#else ++#define sysrq_showallregs_op (*(struct sysrq_key_op *)0) ++#endif ++ + static void sysrq_handle_showstate(int key, struct tty_struct *tty) + { + show_state(); +@@ -340,7 +356,7 @@ + &sysrq_kill_op, /* i */ + NULL, /* j */ + &sysrq_SAK_op, /* k */ +- NULL, /* l */ ++ &sysrq_showallregs_op, /* l */ + &sysrq_showmem_op, /* m */ + &sysrq_unrt_op, /* n */ + /* o: This will often be registered as 'Off' at init time */ +diff -Nur custom-source-rt.orig/drivers/char/tty_io.c custom-source-rt/drivers/char/tty_io.c +--- custom-source-rt.orig/drivers/char/tty_io.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/char/tty_io.c 2007-10-02 17:31:08.000000000 +0000 +@@ -257,6 +257,7 @@ + printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " + "!= #fd's(%d) in %s\n", + tty->name, tty->count, count, routine); ++ dump_stack(); + return count; + } + #endif +@@ -3624,10 +3625,14 @@ + tty->buf.tail->commit = tty->buf.tail->used; + spin_unlock_irqrestore(&tty->buf.lock, flags); + ++#ifndef CONFIG_PREEMPT_RT + if (tty->low_latency) + flush_to_ldisc(&tty->buf.work.work); + else + schedule_delayed_work(&tty->buf.work, 1); ++#else ++ flush_to_ldisc(&tty->buf.work.work); ++#endif + } + + EXPORT_SYMBOL(tty_flip_buffer_push); +diff -Nur custom-source-rt.orig/drivers/clocksource/acpi_pm.c custom-source-rt/drivers/clocksource/acpi_pm.c +--- custom-source-rt.orig/drivers/clocksource/acpi_pm.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/clocksource/acpi_pm.c 2007-10-02 17:31:08.000000000 +0000 +@@ -30,13 +30,13 @@ + */ + u32 pmtmr_ioport __read_mostly; + +-static inline u32 read_pmtmr(void) ++static notrace inline u32 read_pmtmr(void) + { + /* mask the output to 24 bits */ + return inl(pmtmr_ioport) & ACPI_PM_MASK; + } + +-u32 acpi_pm_read_verified(void) ++u32 notrace acpi_pm_read_verified(void) + { + u32 v1 = 0, v2 = 0, v3 = 0; + +@@ -56,12 +56,12 @@ + return v2; + } + +-static cycle_t acpi_pm_read_slow(void) ++static notrace cycle_t acpi_pm_read_slow(void) + { + return (cycle_t)acpi_pm_read_verified(); + } + +-static cycle_t acpi_pm_read(void) ++static notrace cycle_t acpi_pm_read(void) + { + return (cycle_t)read_pmtmr(); + } +@@ -71,7 +71,7 @@ + .rating = 200, + .read = acpi_pm_read, + .mask = (cycle_t)ACPI_PM_MASK, +- .mult = 0, /*to be caluclated*/ ++ .mult = 0, /*to be calculated*/ + .shift = 22, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + +diff -Nur custom-source-rt.orig/drivers/cpuidle/Kconfig custom-source-rt/drivers/cpuidle/Kconfig +--- custom-source-rt.orig/drivers/cpuidle/Kconfig 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/Kconfig 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,39 @@ ++menu "CPU idle PM support" ++ ++config CPU_IDLE ++ bool "CPU idle PM support" ++ help ++ CPU idle is a generic framework for supporting software-controlled ++ idle processor power management. It includes modular cross-platform ++ governors that can be swapped during runtime. ++ ++ If you're using a mobile platform that supports CPU idle PM (e.g. ++ an ACPI-capable notebook), you should say Y here. ++ ++if CPU_IDLE ++ ++comment "Governors" ++ ++config CPU_IDLE_GOV_LADDER ++ tristate "'ladder' governor" ++ depends on CPU_IDLE ++ default y ++ help ++ This cpuidle governor promotes and demotes through the supported idle ++ states using residency time and bus master activity as metrics. This ++ algorithm was originally introduced in the old ACPI processor driver. ++ ++config CPU_IDLE_GOV_MENU ++ tristate "'menu' governor" ++ depends on CPU_IDLE && NO_HZ ++ default y ++ help ++ This cpuidle governor evaluates all available states and chooses the ++ deepest state that meets all of the following constraints: BM activity, ++ expected time until next timer interrupt, and last break event time ++ delta. It is designed to minimize power consumption. Currently ++ dynticks is required. ++ ++endif # CPU_IDLE ++ ++endmenu +diff -Nur custom-source-rt.orig/drivers/cpuidle/Makefile custom-source-rt/drivers/cpuidle/Makefile +--- custom-source-rt.orig/drivers/cpuidle/Makefile 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,5 @@ ++# ++# Makefile for cpuidle. ++# ++ ++obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ +diff -Nur custom-source-rt.orig/drivers/cpuidle/cpuidle.c custom-source-rt/drivers/cpuidle/cpuidle.c +--- custom-source-rt.orig/drivers/cpuidle/cpuidle.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/cpuidle.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,306 @@ ++/* ++ * cpuidle.c - core cpuidle infrastructure ++ * ++ * (C) 2006-2007 Venkatesh Pallipadi ++ * Shaohua Li ++ * Adam Belay ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cpuidle.h" ++ ++DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); ++EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices); ++ ++DEFINE_MUTEX(cpuidle_lock); ++LIST_HEAD(cpuidle_detected_devices); ++static void (*pm_idle_old)(void); ++ ++/** ++ * cpuidle_idle_call - the main idle loop ++ * ++ * NOTE: no locks or semaphores should be used here ++ */ ++static void cpuidle_idle_call(void) ++{ ++ struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices); ++ struct cpuidle_state *target_state; ++ int next_state; ++ ++ /* check if the device is ready */ ++ if (!dev || dev->status != CPUIDLE_STATUS_DOIDLE) { ++ if (pm_idle_old) ++ pm_idle_old(); ++ else ++ local_irq_enable(); ++ return; ++ } ++ ++ /* ask the governor for the next state */ ++ next_state = cpuidle_curr_governor->select(dev); ++ if (need_resched()) ++ return; ++ target_state = &dev->states[next_state]; ++ ++ /* enter the state and update stats */ ++ dev->last_residency = target_state->enter(dev, target_state); ++ dev->last_state = target_state; ++ target_state->time += dev->last_residency; ++ target_state->usage++; ++ ++ /* give the governor an opportunity to reflect on the outcome */ ++ if (cpuidle_curr_governor->reflect) ++ cpuidle_curr_governor->reflect(dev); ++} ++ ++/** ++ * cpuidle_install_idle_handler - installs the cpuidle idle loop handler ++ */ ++void cpuidle_install_idle_handler(void) ++{ ++ if (pm_idle != cpuidle_idle_call) { ++ /* Make sure all changes finished before we switch to new idle */ ++ smp_wmb(); ++ pm_idle = cpuidle_idle_call; ++ } ++} ++ ++/** ++ * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler ++ */ ++void cpuidle_uninstall_idle_handler(void) ++{ ++ if (pm_idle != pm_idle_old) { ++ pm_idle = pm_idle_old; ++ cpu_idle_wait(); ++ } ++} ++ ++/** ++ * cpuidle_rescan_device - prepares for a new state configuration ++ * @dev: the target device ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++void cpuidle_rescan_device(struct cpuidle_device *dev) ++{ ++ int i; ++ ++ if (cpuidle_curr_governor->scan) ++ cpuidle_curr_governor->scan(dev); ++ ++ for (i = 0; i < dev->state_count; i++) { ++ dev->states[i].usage = 0; ++ dev->states[i].time = 0; ++ } ++} ++ ++/** ++ * cpuidle_add_device - attaches the driver to a CPU instance ++ * @sys_dev: the system device (driver model CPU representation) ++ */ ++static int cpuidle_add_device(struct sys_device *sys_dev) ++{ ++ int cpu = sys_dev->id; ++ struct cpuidle_device *dev; ++ ++ dev = per_cpu(cpuidle_devices, cpu); ++ ++ mutex_lock(&cpuidle_lock); ++ if (cpu_is_offline(cpu)) { ++ mutex_unlock(&cpuidle_lock); ++ return 0; ++ } ++ ++ if (!dev) { ++ dev = kzalloc(sizeof(struct cpuidle_device), GFP_KERNEL); ++ if (!dev) { ++ mutex_unlock(&cpuidle_lock); ++ return -ENOMEM; ++ } ++ init_completion(&dev->kobj_unregister); ++ per_cpu(cpuidle_devices, cpu) = dev; ++ } ++ dev->cpu = cpu; ++ ++ if (dev->status & CPUIDLE_STATUS_DETECTED) { ++ mutex_unlock(&cpuidle_lock); ++ return 0; ++ } ++ ++ cpuidle_add_sysfs(sys_dev); ++ ++ if (cpuidle_curr_driver) { ++ if (cpuidle_attach_driver(dev)) ++ goto err_ret; ++ } ++ ++ if (cpuidle_curr_governor) { ++ if (cpuidle_attach_governor(dev)) { ++ cpuidle_detach_driver(dev); ++ goto err_ret; ++ } ++ } ++ ++ if (cpuidle_device_can_idle(dev)) ++ cpuidle_install_idle_handler(); ++ ++ list_add(&dev->device_list, &cpuidle_detected_devices); ++ dev->status |= CPUIDLE_STATUS_DETECTED; ++ ++err_ret: ++ mutex_unlock(&cpuidle_lock); ++ ++ return 0; ++} ++ ++/** ++ * __cpuidle_remove_device - detaches the driver from a CPU instance ++ * @sys_dev: the system device (driver model CPU representation) ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++static int __cpuidle_remove_device(struct sys_device *sys_dev) ++{ ++ struct cpuidle_device *dev; ++ ++ dev = per_cpu(cpuidle_devices, sys_dev->id); ++ ++ if (!(dev->status & CPUIDLE_STATUS_DETECTED)) { ++ return 0; ++ } ++ dev->status &= ~CPUIDLE_STATUS_DETECTED; ++ /* NOTE: we don't wait because the cpu is already offline */ ++ if (cpuidle_curr_governor) ++ cpuidle_detach_governor(dev); ++ if (cpuidle_curr_driver) ++ cpuidle_detach_driver(dev); ++ cpuidle_remove_sysfs(sys_dev); ++ list_del(&dev->device_list); ++ wait_for_completion(&dev->kobj_unregister); ++ per_cpu(cpuidle_devices, sys_dev->id) = NULL; ++ kfree(dev); ++ ++ return 0; ++} ++ ++/** ++ * cpuidle_remove_device - detaches the driver from a CPU instance ++ * @sys_dev: the system device (driver model CPU representation) ++ */ ++static int cpuidle_remove_device(struct sys_device *sys_dev) ++{ ++ int ret; ++ mutex_lock(&cpuidle_lock); ++ ret = __cpuidle_remove_device(sys_dev); ++ mutex_unlock(&cpuidle_lock); ++ ++ return ret; ++} ++ ++static struct sysdev_driver cpuidle_sysdev_driver = { ++ .add = cpuidle_add_device, ++ .remove = cpuidle_remove_device, ++}; ++ ++static int cpuidle_cpu_callback(struct notifier_block *nfb, ++ unsigned long action, void *hcpu) ++{ ++ struct sys_device *sys_dev; ++ ++ sys_dev = get_cpu_sysdev((unsigned long)hcpu); ++ ++ switch (action) { ++ case CPU_ONLINE: ++ cpuidle_add_device(sys_dev); ++ break; ++ case CPU_DOWN_PREPARE: ++ mutex_lock(&cpuidle_lock); ++ break; ++ case CPU_DEAD: ++ __cpuidle_remove_device(sys_dev); ++ mutex_unlock(&cpuidle_lock); ++ break; ++ case CPU_DOWN_FAILED: ++ mutex_unlock(&cpuidle_lock); ++ break; ++ } ++ ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block __cpuinitdata cpuidle_cpu_notifier = ++{ ++ .notifier_call = cpuidle_cpu_callback, ++}; ++ ++#ifdef CONFIG_SMP ++ ++static void smp_callback(void *v) ++{ ++ /* we already woke the CPU up, nothing more to do */ ++} ++ ++/* ++ * This function gets called when a part of the kernel has a new latency ++ * requirement. This means we need to get all processors out of their C-state, ++ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that ++ * wakes them all right up. ++ */ ++static int cpuidle_latency_notify(struct notifier_block *b, ++ unsigned long l, void *v) ++{ ++ smp_call_function(smp_callback, NULL, 0, 1); ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block cpuidle_latency_notifier = { ++ .notifier_call = cpuidle_latency_notify, ++}; ++ ++#define latency_notifier_init(x) do { register_latency_notifier(x); } while (0) ++ ++#else /* CONFIG_SMP */ ++ ++#define latency_notifier_init(x) do { } while (0) ++ ++#endif /* CONFIG_SMP */ ++ ++/** ++ * cpuidle_init - core initializer ++ */ ++static int __init cpuidle_init(void) ++{ ++ int ret; ++ ++ pm_idle_old = pm_idle; ++ ++ ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); ++ if (ret) ++ return ret; ++ ++ register_hotcpu_notifier(&cpuidle_cpu_notifier); ++ ++ ret = sysdev_driver_register(&cpu_sysdev_class, &cpuidle_sysdev_driver); ++ ++ if (ret) { ++ cpuidle_remove_class_sysfs(&cpu_sysdev_class); ++ printk(KERN_ERR "cpuidle: failed to initialize\n"); ++ return ret; ++ } ++ ++ latency_notifier_init(&cpuidle_latency_notifier); ++ ++ return 0; ++} ++ ++core_initcall(cpuidle_init); +diff -Nur custom-source-rt.orig/drivers/cpuidle/cpuidle.h custom-source-rt/drivers/cpuidle/cpuidle.h +--- custom-source-rt.orig/drivers/cpuidle/cpuidle.h 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/cpuidle.h 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,50 @@ ++/* ++ * cpuidle.h - The internal header file ++ */ ++ ++#ifndef __DRIVER_CPUIDLE_H ++#define __DRIVER_CPUIDLE_H ++ ++#include ++ ++/* For internal use only */ ++extern struct cpuidle_governor *cpuidle_curr_governor; ++extern struct cpuidle_driver *cpuidle_curr_driver; ++extern struct list_head cpuidle_drivers; ++extern struct list_head cpuidle_governors; ++extern struct list_head cpuidle_detected_devices; ++extern struct mutex cpuidle_lock; ++ ++/* idle loop */ ++extern void cpuidle_install_idle_handler(void); ++extern void cpuidle_uninstall_idle_handler(void); ++extern void cpuidle_rescan_device(struct cpuidle_device *dev); ++ ++/* drivers */ ++extern int cpuidle_attach_driver(struct cpuidle_device *dev); ++extern void cpuidle_detach_driver(struct cpuidle_device *dev); ++extern int cpuidle_switch_driver(struct cpuidle_driver *drv); ++ ++/* governors */ ++extern int cpuidle_attach_governor(struct cpuidle_device *dev); ++extern void cpuidle_detach_governor(struct cpuidle_device *dev); ++extern int cpuidle_switch_governor(struct cpuidle_governor *gov); ++ ++/* sysfs */ ++extern int cpuidle_add_class_sysfs(struct sysdev_class *cls); ++extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls); ++extern int cpuidle_add_driver_sysfs(struct cpuidle_device *device); ++extern void cpuidle_remove_driver_sysfs(struct cpuidle_device *device); ++extern int cpuidle_add_sysfs(struct sys_device *sysdev); ++extern void cpuidle_remove_sysfs(struct sys_device *sysdev); ++ ++/** ++ * cpuidle_device_can_idle - determines if a CPU can utilize the idle loop ++ * @dev: the target CPU ++ */ ++static inline int cpuidle_device_can_idle(struct cpuidle_device *dev) ++{ ++ return (dev->status == CPUIDLE_STATUS_DOIDLE); ++} ++ ++#endif /* __DRIVER_CPUIDLE_H */ +diff -Nur custom-source-rt.orig/drivers/cpuidle/driver.c custom-source-rt/drivers/cpuidle/driver.c +--- custom-source-rt.orig/drivers/cpuidle/driver.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/driver.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,276 @@ ++/* ++ * driver.c - driver support ++ * ++ * (C) 2006-2007 Venkatesh Pallipadi ++ * Shaohua Li ++ * Adam Belay ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++ ++#include "cpuidle.h" ++ ++LIST_HEAD(cpuidle_drivers); ++struct cpuidle_driver *cpuidle_curr_driver; ++ ++ ++/** ++ * cpuidle_attach_driver - attaches a driver to a CPU ++ * @dev: the target CPU ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++int cpuidle_attach_driver(struct cpuidle_device *dev) ++{ ++ int ret; ++ ++ if (dev->status & CPUIDLE_STATUS_DRIVER_ATTACHED) ++ return -EIO; ++ ++ if (!try_module_get(cpuidle_curr_driver->owner)) ++ return -EINVAL; ++ ++ ret = cpuidle_curr_driver->init(dev); ++ if (ret) { ++ module_put(cpuidle_curr_driver->owner); ++ printk(KERN_INFO "cpuidle: driver %s failed to attach to " ++ "cpu %d\n", cpuidle_curr_driver->name, dev->cpu); ++ } else { ++ if (dev->status & CPUIDLE_STATUS_GOVERNOR_ATTACHED) ++ cpuidle_rescan_device(dev); ++ smp_wmb(); ++ dev->status |= CPUIDLE_STATUS_DRIVER_ATTACHED; ++ cpuidle_add_driver_sysfs(dev); ++ } ++ ++ return ret; ++} ++ ++/** ++ * cpuidle_detach_govenor - detaches a driver from a CPU ++ * @dev: the target CPU ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++void cpuidle_detach_driver(struct cpuidle_device *dev) ++{ ++ if (dev->status & CPUIDLE_STATUS_DRIVER_ATTACHED) { ++ cpuidle_remove_driver_sysfs(dev); ++ dev->status &= ~CPUIDLE_STATUS_DRIVER_ATTACHED; ++ if (cpuidle_curr_driver->exit) ++ cpuidle_curr_driver->exit(dev); ++ module_put(cpuidle_curr_driver->owner); ++ } ++} ++ ++/** ++ * __cpuidle_find_driver - finds a driver of the specified name ++ * @str: the name ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++static struct cpuidle_driver * __cpuidle_find_driver(const char *str) ++{ ++ struct cpuidle_driver *drv; ++ ++ list_for_each_entry(drv, &cpuidle_drivers, driver_list) ++ if (!strnicmp(str, drv->name, CPUIDLE_NAME_LEN)) ++ return drv; ++ ++ return NULL; ++} ++ ++/** ++ * cpuidle_switch_driver - changes the driver ++ * @drv: the new target driver ++ * ++ * NOTE: "drv" can be NULL to specify disabled ++ * Must be called with cpuidle_lock aquired. ++ */ ++int cpuidle_switch_driver(struct cpuidle_driver *drv) ++{ ++ struct cpuidle_device *dev; ++ ++ if (drv == cpuidle_curr_driver) ++ return -EINVAL; ++ ++ cpuidle_uninstall_idle_handler(); ++ ++ if (cpuidle_curr_driver) ++ list_for_each_entry(dev, &cpuidle_detected_devices, device_list) ++ cpuidle_detach_driver(dev); ++ ++ cpuidle_curr_driver = drv; ++ ++ if (drv) { ++ int ret = 1; ++ list_for_each_entry(dev, &cpuidle_detected_devices, device_list) ++ if (cpuidle_attach_driver(dev) == 0) ++ ret = 0; ++ ++ /* If attach on all devices fail, switch to NULL driver */ ++ if (ret) ++ cpuidle_curr_driver = NULL; ++ ++ if (cpuidle_curr_driver && cpuidle_curr_governor) { ++ printk(KERN_INFO "cpuidle: using driver %s\n", ++ drv->name); ++ cpuidle_install_idle_handler(); ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * cpuidle_register_driver - registers a driver ++ * @drv: the driver ++ */ ++int cpuidle_register_driver(struct cpuidle_driver *drv) ++{ ++ int ret = -EEXIST; ++ ++ if (!drv || !drv->init) ++ return -EINVAL; ++ ++ mutex_lock(&cpuidle_lock); ++ if (__cpuidle_find_driver(drv->name) == NULL) { ++ ret = 0; ++ list_add_tail(&drv->driver_list, &cpuidle_drivers); ++ if (!cpuidle_curr_driver) ++ cpuidle_switch_driver(drv); ++ } ++ mutex_unlock(&cpuidle_lock); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_register_driver); ++ ++/** ++ * cpuidle_unregister_driver - unregisters a driver ++ * @drv: the driver ++ */ ++void cpuidle_unregister_driver(struct cpuidle_driver *drv) ++{ ++ if (!drv) ++ return; ++ ++ mutex_lock(&cpuidle_lock); ++ if (drv == cpuidle_curr_driver) ++ cpuidle_switch_driver(NULL); ++ list_del(&drv->driver_list); ++ mutex_unlock(&cpuidle_lock); ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); ++ ++static void __cpuidle_force_redetect(struct cpuidle_device *dev) ++{ ++ cpuidle_remove_driver_sysfs(dev); ++ cpuidle_curr_driver->redetect(dev); ++ cpuidle_add_driver_sysfs(dev); ++} ++ ++/** ++ * cpuidle_force_redetect - redetects the idle states of a CPU ++ * ++ * @dev: the CPU to redetect ++ * @drv: the target driver ++ * ++ * Generally, the driver will call this when the supported states set has ++ * changed. (e.g. as the result of an ACPI transition to battery power) ++ */ ++int cpuidle_force_redetect(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv) ++{ ++ int uninstalled = 0; ++ ++ mutex_lock(&cpuidle_lock); ++ ++ if (drv != cpuidle_curr_driver) { ++ mutex_unlock(&cpuidle_lock); ++ return 0; ++ } ++ ++ if (!(dev->status & CPUIDLE_STATUS_DRIVER_ATTACHED) || ++ !cpuidle_curr_driver->redetect) { ++ mutex_unlock(&cpuidle_lock); ++ return -EIO; ++ } ++ ++ if (cpuidle_device_can_idle(dev)) { ++ uninstalled = 1; ++ cpuidle_uninstall_idle_handler(); ++ } ++ ++ __cpuidle_force_redetect(dev); ++ ++ if (cpuidle_device_can_idle(dev)) { ++ cpuidle_rescan_device(dev); ++ cpuidle_install_idle_handler(); ++ } ++ ++ /* other devices are still ok */ ++ if (uninstalled) ++ cpuidle_install_idle_handler(); ++ ++ mutex_unlock(&cpuidle_lock); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_force_redetect); ++ ++/** ++ * cpuidle_force_redetect_devices - redetects the idle states of all CPUs ++ * ++ * @drv: the target driver ++ * ++ * Generally, the driver will call this when the supported states set has ++ * changed. (e.g. as the result of an ACPI transition to battery power) ++ */ ++int cpuidle_force_redetect_devices(struct cpuidle_driver *drv) ++{ ++ struct cpuidle_device *dev; ++ int ret = 0; ++ ++ mutex_lock(&cpuidle_lock); ++ ++ if (drv != cpuidle_curr_driver) ++ goto out; ++ ++ if (!cpuidle_curr_driver->redetect) { ++ ret = -EIO; ++ goto out; ++ } ++ ++ cpuidle_uninstall_idle_handler(); ++ ++ list_for_each_entry(dev, &cpuidle_detected_devices, device_list) ++ __cpuidle_force_redetect(dev); ++ ++ cpuidle_install_idle_handler(); ++out: ++ mutex_unlock(&cpuidle_lock); ++ return ret; ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_force_redetect_devices); ++ ++/** ++ * cpuidle_get_bm_activity - determines if BM activity has occured ++ */ ++int cpuidle_get_bm_activity(void) ++{ ++ if (cpuidle_curr_driver->bm_check) ++ return cpuidle_curr_driver->bm_check(); ++ else ++ return 0; ++} ++EXPORT_SYMBOL_GPL(cpuidle_get_bm_activity); ++ +diff -Nur custom-source-rt.orig/drivers/cpuidle/governor.c custom-source-rt/drivers/cpuidle/governor.c +--- custom-source-rt.orig/drivers/cpuidle/governor.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/governor.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,187 @@ ++/* ++ * governor.c - governor support ++ * ++ * (C) 2006-2007 Venkatesh Pallipadi ++ * Shaohua Li ++ * Adam Belay ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++ ++#include "cpuidle.h" ++ ++LIST_HEAD(cpuidle_governors); ++struct cpuidle_governor *cpuidle_curr_governor; ++ ++ ++/** ++ * cpuidle_attach_governor - attaches a governor to a CPU ++ * @dev: the target CPU ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++int cpuidle_attach_governor(struct cpuidle_device *dev) ++{ ++ int ret = 0; ++ ++ if(dev->status & CPUIDLE_STATUS_GOVERNOR_ATTACHED) ++ return -EIO; ++ ++ if (!try_module_get(cpuidle_curr_governor->owner)) ++ return -EINVAL; ++ ++ if (cpuidle_curr_governor->init) ++ ret = cpuidle_curr_governor->init(dev); ++ if (ret) { ++ module_put(cpuidle_curr_governor->owner); ++ printk(KERN_ERR "cpuidle: governor %s failed to attach to cpu %d\n", ++ cpuidle_curr_governor->name, dev->cpu); ++ } else { ++ if (dev->status & CPUIDLE_STATUS_DRIVER_ATTACHED) ++ cpuidle_rescan_device(dev); ++ smp_wmb(); ++ dev->status |= CPUIDLE_STATUS_GOVERNOR_ATTACHED; ++ } ++ ++ return ret; ++} ++ ++/** ++ * cpuidle_detach_govenor - detaches a governor from a CPU ++ * @dev: the target CPU ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++void cpuidle_detach_governor(struct cpuidle_device *dev) ++{ ++ if (dev->status & CPUIDLE_STATUS_GOVERNOR_ATTACHED) { ++ dev->status &= ~CPUIDLE_STATUS_GOVERNOR_ATTACHED; ++ if (cpuidle_curr_governor->exit) ++ cpuidle_curr_governor->exit(dev); ++ module_put(cpuidle_curr_governor->owner); ++ } ++} ++ ++/** ++ * __cpuidle_find_governor - finds a governor of the specified name ++ * @str: the name ++ * ++ * Must be called with cpuidle_lock aquired. ++ */ ++static struct cpuidle_governor * __cpuidle_find_governor(const char *str) ++{ ++ struct cpuidle_governor *gov; ++ ++ list_for_each_entry(gov, &cpuidle_governors, governor_list) ++ if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN)) ++ return gov; ++ ++ return NULL; ++} ++ ++/** ++ * cpuidle_switch_governor - changes the governor ++ * @gov: the new target governor ++ * ++ * NOTE: "gov" can be NULL to specify disabled ++ * Must be called with cpuidle_lock aquired. ++ */ ++int cpuidle_switch_governor(struct cpuidle_governor *gov) ++{ ++ struct cpuidle_device *dev; ++ ++ if (gov == cpuidle_curr_governor) ++ return -EINVAL; ++ ++ cpuidle_uninstall_idle_handler(); ++ ++ if (cpuidle_curr_governor) ++ list_for_each_entry(dev, &cpuidle_detected_devices, device_list) ++ cpuidle_detach_governor(dev); ++ ++ cpuidle_curr_governor = gov; ++ ++ if (gov) { ++ list_for_each_entry(dev, &cpuidle_detected_devices, device_list) ++ cpuidle_attach_governor(dev); ++ if (cpuidle_curr_driver) ++ cpuidle_install_idle_handler(); ++ printk(KERN_INFO "cpuidle: using governor %s\n", gov->name); ++ } ++ ++ return 0; ++} ++ ++/** ++ * cpuidle_register_governor - registers a governor ++ * @gov: the governor ++ */ ++int cpuidle_register_governor(struct cpuidle_governor *gov) ++{ ++ int ret = -EEXIST; ++ ++ if (!gov || !gov->select) ++ return -EINVAL; ++ ++ mutex_lock(&cpuidle_lock); ++ if (__cpuidle_find_governor(gov->name) == NULL) { ++ ret = 0; ++ list_add_tail(&gov->governor_list, &cpuidle_governors); ++ if (!cpuidle_curr_governor || ++ cpuidle_curr_governor->rating < gov->rating) ++ cpuidle_switch_governor(gov); ++ } ++ mutex_unlock(&cpuidle_lock); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_register_governor); ++ ++/** ++ * cpuidle_replace_governor - find a replacement governor ++ * @exclude_rating: the rating that will be skipped while looking for ++ * new governor. ++ */ ++struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating) ++{ ++ struct cpuidle_governor *gov; ++ struct cpuidle_governor *ret_gov = NULL; ++ unsigned int max_rating = 0; ++ ++ list_for_each_entry(gov, &cpuidle_governors, governor_list) { ++ if (gov->rating == exclude_rating) ++ continue; ++ if (gov->rating > max_rating) { ++ max_rating = gov->rating; ++ ret_gov = gov; ++ } ++ } ++ ++ return ret_gov; ++} ++ ++/** ++ * cpuidle_unregister_governor - unregisters a governor ++ * @gov: the governor ++ */ ++void cpuidle_unregister_governor(struct cpuidle_governor *gov) ++{ ++ if (!gov) ++ return; ++ ++ mutex_lock(&cpuidle_lock); ++ if (gov == cpuidle_curr_governor) { ++ struct cpuidle_governor *new_gov; ++ new_gov = cpuidle_replace_governor(gov->rating); ++ cpuidle_switch_governor(new_gov); ++ } ++ list_del(&gov->governor_list); ++ mutex_unlock(&cpuidle_lock); ++} ++ ++EXPORT_SYMBOL_GPL(cpuidle_unregister_governor); +diff -Nur custom-source-rt.orig/drivers/cpuidle/governors/Makefile custom-source-rt/drivers/cpuidle/governors/Makefile +--- custom-source-rt.orig/drivers/cpuidle/governors/Makefile 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/governors/Makefile 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,6 @@ ++# ++# Makefile for cpuidle governors. ++# ++ ++obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o ++obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o +diff -Nur custom-source-rt.orig/drivers/cpuidle/governors/ladder.c custom-source-rt/drivers/cpuidle/governors/ladder.c +--- custom-source-rt.orig/drivers/cpuidle/governors/ladder.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/governors/ladder.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,228 @@ ++/* ++ * ladder.c - the residency ladder algorithm ++ * ++ * Copyright (C) 2001, 2002 Andy Grover ++ * Copyright (C) 2001, 2002 Paul Diefenbaugh ++ * Copyright (C) 2004, 2005 Dominik Brodowski ++ * ++ * (C) 2006-2007 Venkatesh Pallipadi ++ * Shaohua Li ++ * Adam Belay ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define PROMOTION_COUNT 4 ++#define DEMOTION_COUNT 1 ++ ++/* ++ * bm_history -- bit-mask with a bit per jiffy of bus-master activity ++ * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms ++ * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms ++ * 100 HZ: 0x0000000F: 4 jiffies = 40ms ++ * reduce history for more aggressive entry into C3 ++ */ ++static unsigned int bm_history __read_mostly = ++ (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); ++module_param(bm_history, uint, 0644); ++ ++struct ladder_device_state { ++ struct { ++ u32 promotion_count; ++ u32 demotion_count; ++ u32 promotion_time; ++ u32 demotion_time; ++ u32 bm; ++ } threshold; ++ struct { ++ int promotion_count; ++ int demotion_count; ++ } stats; ++}; ++ ++struct ladder_device { ++ struct ladder_device_state states[CPUIDLE_STATE_MAX]; ++ unsigned int bm_check:1; ++ unsigned long bm_check_timestamp; ++ unsigned long bm_activity; /* FIXME: bm activity should be global */ ++ int last_state_idx; ++}; ++ ++/** ++ * ladder_do_selection - prepares private data for a state change ++ * @ldev: the ladder device ++ * @old_idx: the current state index ++ * @new_idx: the new target state index ++ */ ++static inline void ladder_do_selection(struct ladder_device *ldev, ++ int old_idx, int new_idx) ++{ ++ ldev->states[old_idx].stats.promotion_count = 0; ++ ldev->states[old_idx].stats.demotion_count = 0; ++ ldev->last_state_idx = new_idx; ++} ++ ++/** ++ * ladder_select_state - selects the next state to enter ++ * @dev: the CPU ++ */ ++static int ladder_select_state(struct cpuidle_device *dev) ++{ ++ struct ladder_device *ldev = dev->governor_data; ++ struct ladder_device_state *last_state; ++ int last_residency, last_idx = ldev->last_state_idx; ++ ++ if (unlikely(!ldev)) ++ return 0; ++ ++ last_state = &ldev->states[last_idx]; ++ ++ /* demote if within BM threshold */ ++ if (ldev->bm_check) { ++ unsigned long diff; ++ ++ diff = jiffies - ldev->bm_check_timestamp; ++ if (diff > 31) ++ diff = 31; ++ ++ ldev->bm_activity <<= diff; ++ if (cpuidle_get_bm_activity()) ++ ldev->bm_activity |= ((1 << diff) - 1); ++ ++ ldev->bm_check_timestamp = jiffies; ++ if ((last_idx > 0) && ++ (last_state->threshold.bm & ldev->bm_activity)) { ++ ladder_do_selection(ldev, last_idx, last_idx - 1); ++ return last_idx - 1; ++ } ++ } ++ ++ if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) ++ last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency; ++ else ++ last_residency = last_state->threshold.promotion_time + 1; ++ ++ /* consider promotion */ ++ if (last_idx < dev->state_count - 1 && ++ last_residency > last_state->threshold.promotion_time && ++ dev->states[last_idx + 1].exit_latency <= system_latency_constraint()) { ++ last_state->stats.promotion_count++; ++ last_state->stats.demotion_count = 0; ++ if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) { ++ ladder_do_selection(ldev, last_idx, last_idx + 1); ++ return last_idx + 1; ++ } ++ } ++ ++ /* consider demotion */ ++ if (last_idx > 0 && ++ last_residency < last_state->threshold.demotion_time) { ++ last_state->stats.demotion_count++; ++ last_state->stats.promotion_count = 0; ++ if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) { ++ ladder_do_selection(ldev, last_idx, last_idx - 1); ++ return last_idx - 1; ++ } ++ } ++ ++ /* otherwise remain at the current state */ ++ return last_idx; ++} ++ ++/** ++ * ladder_scan_device - scans a CPU's states and does setup ++ * @dev: the CPU ++ */ ++static void ladder_scan_device(struct cpuidle_device *dev) ++{ ++ int i, bm_check = 0; ++ struct ladder_device *ldev = dev->governor_data; ++ struct ladder_device_state *lstate; ++ struct cpuidle_state *state; ++ ++ ldev->last_state_idx = 0; ++ ldev->bm_check_timestamp = 0; ++ ldev->bm_activity = 0; ++ ++ for (i = 0; i < dev->state_count; i++) { ++ state = &dev->states[i]; ++ lstate = &ldev->states[i]; ++ ++ lstate->stats.promotion_count = 0; ++ lstate->stats.demotion_count = 0; ++ ++ lstate->threshold.promotion_count = PROMOTION_COUNT; ++ lstate->threshold.demotion_count = DEMOTION_COUNT; ++ ++ if (i < dev->state_count - 1) ++ lstate->threshold.promotion_time = state->exit_latency; ++ if (i > 0) ++ lstate->threshold.demotion_time = state->exit_latency; ++ if (state->flags & CPUIDLE_FLAG_CHECK_BM) { ++ lstate->threshold.bm = bm_history; ++ bm_check = 1; ++ } else ++ lstate->threshold.bm = 0; ++ } ++ ++ ldev->bm_check = bm_check; ++} ++ ++/** ++ * ladder_init_device - initializes a CPU-instance ++ * @dev: the CPU ++ */ ++static int ladder_init_device(struct cpuidle_device *dev) ++{ ++ dev->governor_data = kmalloc(sizeof(struct ladder_device), GFP_KERNEL); ++ ++ return !dev->governor_data; ++} ++ ++/** ++ * ladder_exit_device - exits a CPU-instance ++ * @dev: the CPU ++ */ ++static void ladder_exit_device(struct cpuidle_device *dev) ++{ ++ kfree(dev->governor_data); ++} ++ ++static struct cpuidle_governor ladder_governor = { ++ .name = "ladder", ++ .rating = 10, ++ .init = ladder_init_device, ++ .exit = ladder_exit_device, ++ .scan = ladder_scan_device, ++ .select = ladder_select_state, ++ .owner = THIS_MODULE, ++}; ++ ++/** ++ * init_ladder - initializes the governor ++ */ ++static int __init init_ladder(void) ++{ ++ return cpuidle_register_governor(&ladder_governor); ++} ++ ++/** ++ * exit_ladder - exits the governor ++ */ ++static void __exit exit_ladder(void) ++{ ++ cpuidle_unregister_governor(&ladder_governor); ++} ++ ++MODULE_LICENSE("GPL"); ++module_init(init_ladder); ++module_exit(exit_ladder); +diff -Nur custom-source-rt.orig/drivers/cpuidle/governors/menu.c custom-source-rt/drivers/cpuidle/governors/menu.c +--- custom-source-rt.orig/drivers/cpuidle/governors/menu.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/governors/menu.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,181 @@ ++/* ++ * menu.c - the menu idle governor ++ * ++ * Copyright (C) 2006-2007 Adam Belay ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BM_HOLDOFF 20000 /* 20 ms */ ++#define DEMOTION_THRESHOLD 5 ++#define DEMOTION_TIMEOUT_MULTIPLIER 1000 ++ ++struct menu_device { ++ int last_state_idx; ++ ++ int deepest_break_state; ++ struct timespec break_expire_time_ts; ++ int break_last_cnt; ++ ++ int deepest_bm_state; ++ int bm_elapsed_us; ++ int bm_holdoff_us; ++}; ++ ++static DEFINE_PER_CPU(struct menu_device, menu_devices); ++ ++/** ++ * menu_select - selects the next idle state to enter ++ * @dev: the CPU ++ */ ++static int menu_select(struct cpuidle_device *dev) ++{ ++ struct menu_device *data = &__get_cpu_var(menu_devices); ++ int i, expected_us, max_state = dev->state_count; ++ ++ /* discard BM history because it is sticky */ ++ cpuidle_get_bm_activity(); ++ ++ /* determine the expected residency time */ ++ expected_us = (s32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000; ++ ++ /* determine the maximum state compatible with current BM status */ ++ if (cpuidle_get_bm_activity()) ++ data->bm_elapsed_us = 0; ++ if (data->bm_elapsed_us <= data->bm_holdoff_us) ++ max_state = data->deepest_bm_state + 1; ++ ++ /* determine the maximum state compatible with recent idle breaks */ ++ if (data->deepest_break_state >= 0) { ++ struct timespec now; ++ ktime_get_ts(&now); ++ if (timespec_compare(&data->break_expire_time_ts, &now) > 0) { ++ max_state = min(max_state, ++ data->deepest_break_state + 1); ++ } else { ++ data->deepest_break_state = -1; ++ } ++ } ++ ++ /* find the deepest idle state that satisfies our constraints */ ++ for (i = 1; i < max_state; i++) { ++ struct cpuidle_state *s = &dev->states[i]; ++ ++ if (s->target_residency > expected_us) ++ break; ++ ++ if (s->exit_latency > system_latency_constraint()) ++ break; ++ } ++ ++ if (data->last_state_idx != i - 1) ++ data->break_last_cnt = 0; ++ ++ data->last_state_idx = i - 1; ++ return i - 1; ++} ++ ++/** ++ * menu_reflect - attempts to guess what happened after entry ++ * @dev: the CPU ++ * ++ * NOTE: it's important to be fast here because this operation will add to ++ * the overall exit latency. ++ */ ++static void menu_reflect(struct cpuidle_device *dev) ++{ ++ struct menu_device *data = &__get_cpu_var(menu_devices); ++ int last_idx = data->last_state_idx; ++ int measured_us = cpuidle_get_last_residency(dev); ++ struct cpuidle_state *target = &dev->states[last_idx]; ++ ++ /* ++ * Ugh, this idle state doesn't support residency measurements, so we ++ * are basically lost in the dark. As a compromise, assume we slept ++ * for one full standard timer tick. However, be aware that this ++ * could potentially result in a suboptimal state transition. ++ */ ++ if (!(target->flags & CPUIDLE_FLAG_TIME_VALID)) ++ measured_us = USEC_PER_SEC / HZ; ++ ++ data->bm_elapsed_us += measured_us; ++ ++ if (data->last_state_idx == 0) ++ return; ++ ++ /* ++ * Did something other than the timer interrupt ++ * cause an early break event? ++ */ ++ if (unlikely(measured_us < target->target_residency)) { ++ if (data->break_last_cnt > DEMOTION_THRESHOLD) { ++ data->deepest_break_state = data->last_state_idx - 1; ++ ktime_get_ts(&data->break_expire_time_ts); ++ timespec_add_ns(&data->break_expire_time_ts, ++ target->target_residency * ++ DEMOTION_TIMEOUT_MULTIPLIER); ++ } else { ++ data->break_last_cnt++; ++ } ++ } else { ++ if (data->break_last_cnt > 0) ++ data->break_last_cnt--; ++ } ++} ++ ++/** ++ * menu_scan_device - scans a CPU's states and does setup ++ * @dev: the CPU ++ */ ++static void menu_scan_device(struct cpuidle_device *dev) ++{ ++ struct menu_device *data = &per_cpu(menu_devices, dev->cpu); ++ int i; ++ ++ data->last_state_idx = 0; ++ data->bm_elapsed_us = 0; ++ data->bm_holdoff_us = BM_HOLDOFF; ++ data->deepest_break_state = -1; ++ ++ for (i = 1; i < dev->state_count; i++) ++ if (dev->states[i].flags & CPUIDLE_FLAG_CHECK_BM) ++ break; ++ data->deepest_bm_state = i - 1; ++} ++ ++struct cpuidle_governor menu_governor = { ++ .name = "menu", ++ .rating = 20, ++ .scan = menu_scan_device, ++ .select = menu_select, ++ .reflect = menu_reflect, ++ .owner = THIS_MODULE, ++}; ++ ++/** ++ * init_menu - initializes the governor ++ */ ++static int __init init_menu(void) ++{ ++ return cpuidle_register_governor(&menu_governor); ++} ++ ++/** ++ * exit_menu - exits the governor ++ */ ++static void __exit exit_menu(void) ++{ ++ cpuidle_unregister_governor(&menu_governor); ++} ++ ++MODULE_LICENSE("GPL"); ++module_init(init_menu); ++module_exit(exit_menu); +diff -Nur custom-source-rt.orig/drivers/cpuidle/sysfs.c custom-source-rt/drivers/cpuidle/sysfs.c +--- custom-source-rt.orig/drivers/cpuidle/sysfs.c 1970-01-01 00:00:00.000000000 +0000 ++++ custom-source-rt/drivers/cpuidle/sysfs.c 2007-10-02 17:31:08.000000000 +0000 +@@ -0,0 +1,393 @@ ++/* ++ * sysfs.c - sysfs support ++ * ++ * (C) 2006-2007 Shaohua Li ++ * ++ * This code is licenced under the GPL. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "cpuidle.h" ++ ++static unsigned int sysfs_switch; ++static int __init cpuidle_sysfs_setup(char *unused) ++{ ++ sysfs_switch = 1; ++ return 1; ++} ++__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); ++ ++static ssize_t show_available_drivers(struct sys_device *dev, char *buf) ++{ ++ ssize_t i = 0; ++ struct cpuidle_driver *tmp; ++ ++ mutex_lock(&cpuidle_lock); ++ list_for_each_entry(tmp, &cpuidle_drivers, driver_list) { ++ if (i >= (ssize_t)((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2)) ++ goto out; ++ i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name); ++ } ++out: ++ i+= sprintf(&buf[i], "\n"); ++ mutex_unlock(&cpuidle_lock); ++ return i; ++} ++ ++static ssize_t show_available_governors(struct sys_device *dev, char *buf) ++{ ++ ssize_t i = 0; ++ struct cpuidle_governor *tmp; ++ ++ mutex_lock(&cpuidle_lock); ++ list_for_each_entry(tmp, &cpuidle_governors, governor_list) { ++ if (i >= (ssize_t)((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2)) ++ goto out; ++ i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name); ++ } ++ if (list_empty(&cpuidle_governors)) ++ i+= sprintf(&buf[i], "no governors"); ++out: ++ i+= sprintf(&buf[i], "\n"); ++ mutex_unlock(&cpuidle_lock); ++ return i; ++} ++ ++static ssize_t show_current_driver(struct sys_device *dev, char *buf) ++{ ++ ssize_t ret; ++ ++ mutex_lock(&cpuidle_lock); ++ ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name); ++ mutex_unlock(&cpuidle_lock); ++ return ret; ++} ++ ++static ssize_t store_current_driver(struct sys_device *dev, ++ const char *buf, size_t count) ++{ ++ char str[CPUIDLE_NAME_LEN]; ++ int len = count; ++ struct cpuidle_driver *tmp, *found = NULL; ++ ++ if (len > CPUIDLE_NAME_LEN) ++ len = CPUIDLE_NAME_LEN; ++ ++ if (sscanf(buf, "%s", str) != 1) ++ return -EINVAL; ++ ++ mutex_lock(&cpuidle_lock); ++ list_for_each_entry(tmp, &cpuidle_drivers, driver_list) { ++ if (strncmp(tmp->name, str, CPUIDLE_NAME_LEN) == 0) { ++ found = tmp; ++ break; ++ } ++ } ++ if (found) ++ cpuidle_switch_driver(found); ++ mutex_unlock(&cpuidle_lock); ++ ++ return count; ++} ++ ++static ssize_t show_current_governor(struct sys_device *dev, char *buf) ++{ ++ ssize_t i; ++ ++ mutex_lock(&cpuidle_lock); ++ if (cpuidle_curr_governor) ++ i = sprintf(buf, "%s\n", cpuidle_curr_governor->name); ++ else ++ i = sprintf(buf, "no governor\n"); ++ mutex_unlock(&cpuidle_lock); ++ ++ return i; ++} ++ ++static ssize_t store_current_governor(struct sys_device *dev, ++ const char *buf, size_t count) ++{ ++ char str[CPUIDLE_NAME_LEN]; ++ int len = count; ++ struct cpuidle_governor *tmp, *found = NULL; ++ ++ if (len > CPUIDLE_NAME_LEN) ++ len = CPUIDLE_NAME_LEN; ++ ++ if (sscanf(buf, "%s", str) != 1) ++ return -EINVAL; ++ ++ mutex_lock(&cpuidle_lock); ++ list_for_each_entry(tmp, &cpuidle_governors, governor_list) { ++ if (strncmp(tmp->name, str, CPUIDLE_NAME_LEN) == 0) { ++ found = tmp; ++ break; ++ } ++ } ++ if (found) ++ cpuidle_switch_governor(found); ++ mutex_unlock(&cpuidle_lock); ++ ++ return count; ++} ++ ++static SYSDEV_ATTR(current_driver_ro, 0444, show_current_driver, NULL); ++static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL); ++ ++static struct attribute *cpuclass_default_attrs[] = { ++ &attr_current_driver_ro.attr, ++ &attr_current_governor_ro.attr, ++ NULL ++}; ++ ++static SYSDEV_ATTR(available_drivers, 0444, show_available_drivers, NULL); ++static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL); ++static SYSDEV_ATTR(current_driver, 0644, show_current_driver, ++ store_current_driver); ++static SYSDEV_ATTR(current_governor, 0644, show_current_governor, ++ store_current_governor); ++ ++static struct attribute *cpuclass_switch_attrs[] = { ++ &attr_available_drivers.attr, ++ &attr_available_governors.attr, ++ &attr_current_driver.attr, ++ &attr_current_governor.attr, ++ NULL ++}; ++ ++static struct attribute_group cpuclass_attr_group = { ++ .attrs = cpuclass_default_attrs, ++ .name = "cpuidle", ++}; ++ ++/** ++ * cpuidle_add_class_sysfs - add CPU global sysfs attributes ++ */ ++int cpuidle_add_class_sysfs(struct sysdev_class *cls) ++{ ++ if (sysfs_switch) ++ cpuclass_attr_group.attrs = cpuclass_switch_attrs; ++ ++ return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group); ++} ++ ++/** ++ * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes ++ */ ++void cpuidle_remove_class_sysfs(struct sysdev_class *cls) ++{ ++ sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group); ++} ++ ++struct cpuidle_attr { ++ struct attribute attr; ++ ssize_t (*show)(struct cpuidle_device *, char *); ++ ssize_t (*store)(struct cpuidle_device *, const char *, size_t count); ++}; ++ ++#define define_one_ro(_name, show) \ ++ static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL) ++#define define_one_rw(_name, show, store) \ ++ static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store) ++ ++#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj) ++#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr) ++static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf) ++{ ++ int ret = -EIO; ++ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); ++ struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); ++ ++ if (cattr->show) { ++ mutex_lock(&cpuidle_lock); ++ ret = cattr->show(dev, buf); ++ mutex_unlock(&cpuidle_lock); ++ } ++ return ret; ++} ++ ++static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr, ++ const char * buf, size_t count) ++{ ++ int ret = -EIO; ++ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); ++ struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); ++ ++ if (cattr->store) { ++ mutex_lock(&cpuidle_lock); ++ ret = cattr->store(dev, buf, count); ++ mutex_unlock(&cpuidle_lock); ++ } ++ return ret; ++} ++ ++static struct sysfs_ops cpuidle_sysfs_ops = { ++ .show = cpuidle_show, ++ .store = cpuidle_store, ++}; ++ ++static void cpuidle_sysfs_release(struct kobject *kobj) ++{ ++ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); ++ ++ complete(&dev->kobj_unregister); ++} ++ ++static struct kobj_type ktype_cpuidle = { ++ .sysfs_ops = &cpuidle_sysfs_ops, ++ .release = cpuidle_sysfs_release, ++}; ++ ++struct cpuidle_state_attr { ++ struct attribute attr; ++ ssize_t (*show)(struct cpuidle_state *, char *); ++ ssize_t (*store)(struct cpuidle_state *, const char *, size_t); ++}; ++ ++#define define_one_state_ro(_name, show) \ ++static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) ++ ++#define define_show_state_function(_name) \ ++static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ ++{ \ ++ return sprintf(buf, "%d\n", state->_name);\ ++} ++ ++define_show_state_function(exit_latency) ++define_show_state_function(power_usage) ++define_show_state_function(usage) ++define_show_state_function(time) ++define_one_state_ro(latency, show_state_exit_latency); ++define_one_state_ro(power, show_state_power_usage); ++define_one_state_ro(usage, show_state_usage); ++define_one_state_ro(time, show_state_time); ++ ++static struct attribute *cpuidle_state_default_attrs[] = { ++ &attr_latency.attr, ++ &attr_power.attr, ++ &attr_usage.attr, ++ &attr_time.attr, ++ NULL ++}; ++ ++#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj) ++#define kobj_to_state(k) (kobj_to_state_obj(k)->state) ++#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr) ++static ssize_t cpuidle_state_show(struct kobject * kobj, ++ struct attribute * attr ,char * buf) ++{ ++ int ret = -EIO; ++ struct cpuidle_state *state = kobj_to_state(kobj); ++ struct cpuidle_state_attr * cattr = attr_to_stateattr(attr); ++ ++ if (cattr->show) ++ ret = cattr->show(state, buf); ++ ++ return ret; ++} ++ ++static struct sysfs_ops cpuidle_state_sysfs_ops = { ++ .show = cpuidle_state_show, ++}; ++ ++static void cpuidle_state_sysfs_release(struct kobject *kobj) ++{ ++ struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj); ++ ++ complete(&state_obj->kobj_unregister); ++} ++ ++static struct kobj_type ktype_state_cpuidle = { ++ .sysfs_ops = &cpuidle_state_sysfs_ops, ++ .default_attrs = cpuidle_state_default_attrs, ++ .release = cpuidle_state_sysfs_release, ++}; ++ ++static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i) ++{ ++ kobject_unregister(&device->kobjs[i]->kobj); ++ wait_for_completion(&device->kobjs[i]->kobj_unregister); ++ kfree(device->kobjs[i]); ++ device->kobjs[i] = NULL; ++} ++ ++/** ++ * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes ++ * @device: the target device ++ */ ++int cpuidle_add_driver_sysfs(struct cpuidle_device *device) ++{ ++ int i, ret = -ENOMEM; ++ struct cpuidle_state_kobj *kobj; ++ ++ /* state statistics */ ++ for (i = 0; i < device->state_count; i++) { ++ kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); ++ if (!kobj) ++ goto error_state; ++ kobj->state = &device->states[i]; ++ init_completion(&kobj->kobj_unregister); ++ ++ kobj->kobj.parent = &device->kobj; ++ kobj->kobj.ktype = &ktype_state_cpuidle; ++ kobject_set_name(&kobj->kobj, "state%d", i); ++ ret = kobject_register(&kobj->kobj); ++ if (ret) { ++ kfree(kobj); ++ goto error_state; ++ } ++ device->kobjs[i] = kobj; ++ } ++ ++ return 0; ++ ++error_state: ++ for (i = i - 1; i >= 0; i--) ++ cpuidle_free_state_kobj(device, i); ++ return ret; ++} ++ ++/** ++ * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes ++ * @device: the target device ++ */ ++void cpuidle_remove_driver_sysfs(struct cpuidle_device *device) ++{ ++ int i; ++ ++ for (i = 0; i < device->state_count; i++) ++ cpuidle_free_state_kobj(device, i); ++} ++ ++/** ++ * cpuidle_add_sysfs - creates a sysfs instance for the target device ++ * @sysdev: the target device ++ */ ++int cpuidle_add_sysfs(struct sys_device *sysdev) ++{ ++ int cpu = sysdev->id; ++ struct cpuidle_device *dev; ++ ++ dev = per_cpu(cpuidle_devices, cpu); ++ dev->kobj.parent = &sysdev->kobj; ++ dev->kobj.ktype = &ktype_cpuidle; ++ kobject_set_name(&dev->kobj, "%s", "cpuidle"); ++ return kobject_register(&dev->kobj); ++} ++ ++/** ++ * cpuidle_remove_sysfs - deletes a sysfs instance on the target device ++ * @sysdev: the target device ++ */ ++void cpuidle_remove_sysfs(struct sys_device *sysdev) ++{ ++ int cpu = sysdev->id; ++ struct cpuidle_device *dev; ++ ++ dev = per_cpu(cpuidle_devices, cpu); ++ kobject_unregister(&dev->kobj); ++} +diff -Nur custom-source-rt.orig/drivers/ide/ide-floppy.c custom-source-rt/drivers/ide/ide-floppy.c +--- custom-source-rt.orig/drivers/ide/ide-floppy.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-floppy.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1667,9 +1667,9 @@ + atapi_status_t status; + unsigned long flags; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + status.all = HWIF(drive)->INB(IDE_STATUS_REG); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + progress_indication = !status.b.dsc ? 0 : 0x10000; + } +diff -Nur custom-source-rt.orig/drivers/ide/ide-io.c custom-source-rt/drivers/ide/ide-io.c +--- custom-source-rt.orig/drivers/ide/ide-io.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-io.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1193,7 +1193,7 @@ + ide_get_lock(ide_intr, hwgroup); + + /* caller must own ide_lock */ +- BUG_ON(!irqs_disabled()); ++ BUG_ON_NONRT(!irqs_disabled()); + + while (!hwgroup->busy) { + hwgroup->busy = 1; +@@ -1461,7 +1461,7 @@ + #endif /* DISABLE_IRQ_NOSYNC */ + /* local CPU only, + * as if we were handling an interrupt */ +- local_irq_disable(); ++ local_irq_disable_nort(); + if (hwgroup->polling) { + startstop = handler(drive); + } else if (drive_is_ready(drive)) { +diff -Nur custom-source-rt.orig/drivers/ide/ide-iops.c custom-source-rt/drivers/ide/ide-iops.c +--- custom-source-rt.orig/drivers/ide/ide-iops.c 2007-10-02 17:10:25.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-iops.c 2007-10-02 17:31:08.000000000 +0000 +@@ -220,10 +220,10 @@ + if (io_32bit) { + if (io_32bit & 2) { + unsigned long flags; +- local_irq_save(flags); ++ local_irq_save_nort(flags); + ata_vlb_sync(drive, IDE_NSECTOR_REG); + hwif->INSL(IDE_DATA_REG, buffer, wcount); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else + hwif->INSL(IDE_DATA_REG, buffer, wcount); + } else { +@@ -242,10 +242,10 @@ + if (io_32bit) { + if (io_32bit & 2) { + unsigned long flags; +- local_irq_save(flags); ++ local_irq_save_nort(flags); + ata_vlb_sync(drive, IDE_NSECTOR_REG); + hwif->OUTSL(IDE_DATA_REG, buffer, wcount); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else + hwif->OUTSL(IDE_DATA_REG, buffer, wcount); + } else { +@@ -540,12 +540,12 @@ + if (!(stat & BUSY_STAT)) + break; + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + *startstop = ide_error(drive, "status timeout", stat); + return 1; + } + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + /* + * Allow status to settle, then read it again. +@@ -718,17 +718,15 @@ + printk("%s: CHECK for good STATUS\n", drive->name); + return 0; + } +- local_irq_save(flags); +- SELECT_MASK(drive, 0); + id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); +- if (!id) { +- local_irq_restore(flags); ++ if (!id) + return 0; +- } ++ local_irq_save_nort(flags); ++ SELECT_MASK(drive, 0); + ata_input_data(drive, id, SECTOR_WORDS); + (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ +- local_irq_enable(); +- local_irq_restore(flags); ++ local_irq_enable_nort(); ++ local_irq_restore_nort(flags); + ide_fix_driveid(id); + if (id) { + drive->id->dma_ultra = id->dma_ultra; +@@ -808,7 +806,7 @@ + if (time_after(jiffies, timeout)) + break; + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + + /* +diff -Nur custom-source-rt.orig/drivers/ide/ide-lib.c custom-source-rt/drivers/ide/ide-lib.c +--- custom-source-rt.orig/drivers/ide/ide-lib.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-lib.c 2007-10-02 17:31:08.000000000 +0000 +@@ -376,15 +376,16 @@ + + static void ide_dump_opcode(ide_drive_t *drive) + { ++ unsigned long flags; + struct request *rq; + u8 opcode = 0; + int found = 0; + +- spin_lock(&ide_lock); ++ spin_lock_irqsave(&ide_lock, flags); + rq = NULL; + if (HWGROUP(drive)) + rq = HWGROUP(drive)->rq; +- spin_unlock(&ide_lock); ++ spin_unlock_irqrestore(&ide_lock, flags); + if (!rq) + return; + if (rq->cmd_type == REQ_TYPE_ATA_CMD || +@@ -413,10 +414,8 @@ + static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) + { + ide_hwif_t *hwif = HWIF(drive); +- unsigned long flags; + u8 err = 0; + +- local_irq_save(flags); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); + if (stat & BUSY_STAT) + printk("Busy "); +@@ -476,7 +475,7 @@ + printk("\n"); + } + ide_dump_opcode(drive); +- local_irq_restore(flags); ++ + return err; + } + +@@ -491,14 +490,11 @@ + + static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) + { +- unsigned long flags; +- + atapi_status_t status; + atapi_error_t error; + + status.all = stat; + error.all = 0; +- local_irq_save(flags); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); + if (status.b.bsy) + printk("Busy "); +@@ -524,7 +520,7 @@ + printk("}\n"); + } + ide_dump_opcode(drive); +- local_irq_restore(flags); ++ + return error.all; + } + +diff -Nur custom-source-rt.orig/drivers/ide/ide-probe.c custom-source-rt/drivers/ide/ide-probe.c +--- custom-source-rt.orig/drivers/ide/ide-probe.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-probe.c 2007-10-02 17:31:08.000000000 +0000 +@@ -141,7 +141,7 @@ + hwif->ata_input_data(drive, id, SECTOR_WORDS); + + drive->id_read = 1; +- local_irq_enable(); ++ local_irq_enable_nort(); + ide_fix_driveid(id); + + #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) +@@ -323,14 +323,14 @@ + unsigned long flags; + + /* local CPU only; some systems need this */ +- local_irq_save(flags); ++ local_irq_save_nort(flags); + /* drive returned ID */ + do_identify(drive, cmd); + /* drive responded with ID */ + rc = 0; + /* clear drive IRQ */ + (void) hwif->INB(IDE_STATUS_REG); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } else { + /* drive refused ID */ + rc = 2; +@@ -807,7 +807,7 @@ + } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); + + } +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + /* + * Use cached IRQ number. It might be (and is...) changed by probe + * code above +diff -Nur custom-source-rt.orig/drivers/ide/ide-taskfile.c custom-source-rt/drivers/ide/ide-taskfile.c +--- custom-source-rt.orig/drivers/ide/ide-taskfile.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/ide-taskfile.c 2007-10-02 17:31:08.000000000 +0000 +@@ -278,7 +278,7 @@ + offset %= PAGE_SIZE; + + #ifdef CONFIG_HIGHMEM +- local_irq_save(flags); ++ local_irq_save_nort(flags); + #endif + buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; + +@@ -298,7 +298,7 @@ + + kunmap_atomic(buf, KM_BIO_SRC_IRQ); + #ifdef CONFIG_HIGHMEM +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + #endif + } + +@@ -464,7 +464,7 @@ + } + + if (!drive->unmask) +- local_irq_disable(); ++ local_irq_disable_nort(); + + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + ide_pio_datablock(drive, rq, 1); +diff -Nur custom-source-rt.orig/drivers/ide/pci/alim15x3.c custom-source-rt/drivers/ide/pci/alim15x3.c +--- custom-source-rt.orig/drivers/ide/pci/alim15x3.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/pci/alim15x3.c 2007-10-02 17:31:08.000000000 +0000 +@@ -325,7 +325,7 @@ + if (r_clc >= 16) + r_clc = 0; + } +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + /* + * PIO mode => ATA FIFO on, ATAPI FIFO off +@@ -347,7 +347,7 @@ + + pci_write_config_byte(dev, port, s_clc); + pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + /* + * setup active rec +@@ -518,7 +518,7 @@ + } + #endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + if (m5229_revision < 0xC2) { + /* +@@ -579,7 +579,7 @@ + out: + pci_dev_put(north); + pci_dev_put(isa_dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + return 0; + } + +@@ -603,7 +603,7 @@ + unsigned long flags; + u8 tmpbyte; + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + if (m5229_revision >= 0xC2) { + /* +@@ -655,7 +655,7 @@ + + pci_write_config_byte(dev, 0x53, tmpbyte); + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + return(ata66); + } +diff -Nur custom-source-rt.orig/drivers/ide/pci/cs5530.c custom-source-rt/drivers/ide/pci/cs5530.c +--- custom-source-rt.orig/drivers/ide/pci/cs5530.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/pci/cs5530.c 2007-10-02 17:31:08.000000000 +0000 +@@ -227,8 +227,8 @@ + goto out; + } + +- spin_lock_irqsave(&ide_lock, flags); +- /* all CPUs (there should only be one CPU with this chipset) */ ++ /* Local CPU. ide_lock is acquired in do_ide_setup_pci_device. */ ++ local_irq_save(flags); + + /* + * Enable BusMaster and MemoryWriteAndInvalidate for the cs5530: +@@ -280,7 +280,7 @@ + pci_write_config_byte(master_0, 0x42, 0x00); + pci_write_config_byte(master_0, 0x43, 0xc1); + +- spin_unlock_irqrestore(&ide_lock, flags); ++ local_irq_restore(flags); + + out: + pci_dev_put(master_0); +diff -Nur custom-source-rt.orig/drivers/ide/pci/hpt366.c custom-source-rt/drivers/ide/pci/hpt366.c +--- custom-source-rt.orig/drivers/ide/pci/hpt366.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/ide/pci/hpt366.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1371,7 +1371,7 @@ + + dma_old = hwif->INB(dmabase + 2); + +- local_irq_save(flags); ++ local_irq_save_nort(flags); + + dma_new = dma_old; + pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma); +@@ -1382,7 +1382,7 @@ + if (dma_new != dma_old) + hwif->OUTB(dma_new, dmabase + 2); + +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + + ide_setup_dma(hwif, dmabase, 8); + } +diff -Nur custom-source-rt.orig/drivers/input/ff-memless.c custom-source-rt/drivers/input/ff-memless.c +--- custom-source-rt.orig/drivers/input/ff-memless.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/input/ff-memless.c 2007-10-02 17:31:08.000000000 +0000 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +diff -Nur custom-source-rt.orig/drivers/input/gameport/gameport.c custom-source-rt/drivers/input/gameport/gameport.c +--- custom-source-rt.orig/drivers/input/gameport/gameport.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/input/gameport/gameport.c 2007-10-02 17:31:08.000000000 +0000 +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include /* HZ */ + #include + #include +@@ -102,12 +103,12 @@ + tx = 1 << 30; + + for(i = 0; i < 50; i++) { +- local_irq_save(flags); ++ local_irq_save_nort(flags); + GET_TIME(t1); + for (t = 0; t < 50; t++) gameport_read(gameport); + GET_TIME(t2); + GET_TIME(t3); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + udelay(i * 10); + if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t; + } +@@ -126,11 +127,11 @@ + tx = 1 << 30; + + for(i = 0; i < 50; i++) { +- local_irq_save(flags); ++ local_irq_save_nort(flags); + rdtscl(t1); + for (t = 0; t < 50; t++) gameport_read(gameport); + rdtscl(t2); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + udelay(i * 10); + if (t2 - t1 < tx) tx = t2 - t1; + } +diff -Nur custom-source-rt.orig/drivers/input/keyboard/atkbd.c custom-source-rt/drivers/input/keyboard/atkbd.c +--- custom-source-rt.orig/drivers/input/keyboard/atkbd.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/input/keyboard/atkbd.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1396,9 +1396,23 @@ + return sprintf(buf, "%lu\n", atkbd->err_count); + } + ++static int __read_mostly noatkbd; ++ ++static int __init noatkbd_setup(char *str) ++{ ++ noatkbd = 1; ++ printk(KERN_INFO "debug: not setting up AT keyboard.\n"); ++ ++ return 1; ++} ++ ++__setup("noatkbd", noatkbd_setup); + + static int __init atkbd_init(void) + { ++ if (noatkbd) ++ return 0; ++ + return serio_register_driver(&atkbd_drv); + } + +diff -Nur custom-source-rt.orig/drivers/input/misc/pcspkr.c custom-source-rt/drivers/input/misc/pcspkr.c +--- custom-source-rt.orig/drivers/input/misc/pcspkr.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/input/misc/pcspkr.c 2007-10-02 17:31:08.000000000 +0000 +@@ -24,7 +24,12 @@ + MODULE_DESCRIPTION("PC Speaker beeper driver"); + MODULE_LICENSE("GPL"); + +-static DEFINE_SPINLOCK(i8253_beep_lock); ++#ifdef CONFIG_X86 ++/* Use the global PIT lock ! */ ++#include ++#else ++static DEFINE_SPINLOCK(i8253_lock); ++#endif + + static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) + { +@@ -43,7 +48,7 @@ + if (value > 20 && value < 32767) + count = PIT_TICK_RATE / value; + +- spin_lock_irqsave(&i8253_beep_lock, flags); ++ spin_lock_irqsave(&i8253_lock, flags); + + if (count) { + /* enable counter 2 */ +@@ -58,7 +63,7 @@ + outb(inb_p(0x61) & 0xFC, 0x61); + } + +- spin_unlock_irqrestore(&i8253_beep_lock, flags); ++ spin_unlock_irqrestore(&i8253_lock, flags); + + return 0; + } +diff -Nur custom-source-rt.orig/drivers/input/mouse/psmouse-base.c custom-source-rt/drivers/input/mouse/psmouse-base.c +--- custom-source-rt.orig/drivers/input/mouse/psmouse-base.c 2007-08-21 04:00:19.000000000 +0000 ++++ custom-source-rt/drivers/input/mouse/psmouse-base.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1565,10 +1565,25 @@ + return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name); + } + ++static int __read_mostly nopsmouse; ++ ++static int __init nopsmouse_setup(char *str) ++{ ++ nopsmouse = 1; ++ printk(KERN_INFO "debug: not setting up psmouse.\n"); ++ ++ return 1; ++} ++ ++__setup("nopsmouse", nopsmouse_setup); ++ + static int __init psmouse_init(void) + { + int err; + ++ if (nopsmouse) ++ return 0; ++ + kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); + if (!kpsmoused_wq) { + printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); +diff -Nur custom-source-rt.orig/drivers/kvm/svm.c custom-source-rt/drivers/kvm/svm.c +--- custom-source-rt.orig/drivers/kvm/svm.c 2007-08-21 04:00:20.000000000 +0000 ++++ custom-source-rt/drivers/kvm/svm.c 2007-10-02 17:31:08.000000000 +0000 +@@ -610,9 +610,17 @@ + + static void svm_vcpu_load(struct kvm_vcpu *vcpu) + { +- int cpu, i; ++ int cpu = raw_smp_processor_id(), i; ++ cpumask_t this_mask = cpumask_of_cpu(cpu); ++ ++ /* ++ * Keep the context preemptible, but do not migrate ++ * away to another CPU. TODO: make sure this persists. ++ * Save/restore original mask. ++ */ ++ if (unlikely(!cpus_equal(current->cpus_allowed, this_mask))) ++ set_cpus_allowed(current, cpumask_of_cpu(cpu)); + +- cpu = get_cpu(); + if (unlikely(cpu != vcpu->cpu)) { + u64 tsc_this, delta; + +@@ -638,7 +646,6 @@ + wrmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]); + + rdtscll(vcpu->host_tsc); +- put_cpu(); + } + + static void svm_vcpu_decache(struct kvm_vcpu *vcpu) +diff -Nur custom-source-rt.orig/drivers/kvm/vmx.c custom-source-rt/drivers/kvm/vmx.c +--- custom-source-rt.orig/drivers/kvm/vmx.c 2007-08-21 04:00:20.000000000 +0000 ++++ custom-source-rt/drivers/kvm/vmx.c 2007-10-02 17:31:08.000000000 +0000 +@@ -241,9 +241,16 @@ + static void vmx_vcpu_load(struct kvm_vcpu *vcpu) + { + u64 phys_addr = __pa(vcpu->vmcs); +- int cpu; ++ int cpu = raw_smp_processor_id(); ++ cpumask_t this_mask = cpumask_of_cpu(cpu); + +- cpu = get_cpu(); ++ /* ++ * Keep the context preemptible, but do not migrate ++ * away to another CPU. TODO: make sure this persists. ++ * Save/restore original mask. ++ */ ++ if (unlikely(!cpus_equal(current->cpus_allowed, this_mask))) ++ set_cpus_allowed(current, cpumask_of_cpu(cpu)); + + if (vcpu->cpu != cpu) + vcpu_clear(vcpu); +@@ -281,7 +288,6 @@ + static void vmx_vcpu_put(struct kvm_vcpu *vcpu) + { + kvm_put_guest_fpu(vcpu); +- put_cpu(); + } + + static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) +@@ -1862,6 +1868,7 @@ + } + #endif + ++ preempt_disable(); + asm ( + /* Store host registers */ + "pushf \n\t" +@@ -2002,6 +2009,8 @@ + + reload_tss(); + } ++ preempt_enable(); ++ + ++vcpu->stat.exits; + + #ifdef CONFIG_X86_64 +diff -Nur custom-source-rt.orig/drivers/macintosh/adb.c custom-source-rt/drivers/macintosh/adb.c +--- custom-source-rt.orig/drivers/macintosh/adb.c 2007-08-21 04:00:20.000000000 +0000 ++++ custom-source-rt/drivers/macintosh/adb.c 2007-10-02 17:31:08.000000000 +0000 +@@ -256,6 +256,8 @@ + sigprocmask(SIG_BLOCK, &blocked, NULL); + flush_signals(current); + ++ down(&adb_probe_mutex); ++ + printk(KERN_INFO "adb: starting probe task...\n"); + do_adb_reset_bus(); + printk(KERN_INFO "adb: finished probe task...\n"); +@@ -282,7 +284,9 @@ + return 0; + } + +- down(&adb_probe_mutex); ++ if (adb_got_sleep) ++ return 0; ++ + schedule_work(&adb_reset_work); + return 0; + } +@@ -345,9 +349,8 @@ + { + switch (when) { + case PBOOK_SLEEP_REQUEST: ++ /* Signal to discontiue probing */ + adb_got_sleep = 1; +- /* We need to get a lock on the probe thread */ +- down(&adb_probe_mutex); + /* Stop autopoll */ + if (adb_controller->autopoll) + adb_controller->autopoll(0); +@@ -356,7 +359,6 @@ + break; + case PBOOK_WAKE: + adb_got_sleep = 0; +- up(&adb_probe_mutex); + adb_reset_bus(); + break; + } +diff -Nur custom-source-rt.orig/drivers/media/dvb/dvb-core/dvb_frontend.c custom-source-rt/drivers/media/dvb/dvb-core/dvb_frontend.c +--- custom-source-rt.orig/drivers/media/dvb/dvb-core/dvb_frontend.c 2007-08-21 04:00:20.000000000 +0000 ++++ custom-source-rt/drivers/media/dvb/dvb-core/dvb_frontend.c 2007-10-02 17:31:08.000000000 +0000 +@@ -98,7 +98,7 @@ + struct dvb_device *dvbdev; + struct dvb_frontend_parameters parameters; + struct dvb_fe_events events; +- struct semaphore sem; ++ struct compat_semaphore sem; + struct list_head list_head; + wait_queue_head_t wait_queue; + struct task_struct *thread; +diff -Nur custom-source-rt.orig/drivers/media/dvb/dvb-core/dvb_frontend.h custom-source-rt/drivers/media/dvb/dvb-core/dvb_frontend.h +--- custom-source-rt.orig/drivers/media/dvb/dvb-core/dvb_frontend.h 2007-08-21 04:00:20.000000000 +0000 ++++ custom-source-rt/drivers/media/dvb/dvb-core/dvb_frontend.h 2007-10-02 17:31:08.000000000 +0000 +@@ -142,7 +142,7 @@ + int eventr; + int overflow; + wait_queue_head_t wait_queue; +- struct semaphore sem; ++ struct compat_semaphore sem; + }; + + struct dvb_frontend { +diff -Nur custom-source-rt.orig/drivers/net/3c527.c custom-source-rt/drivers/net/3c527.c +--- custom-source-rt.orig/drivers/net/3c527.c 2007-08-21 04:00:24.000000000 +0000 ++++ custom-source-rt/drivers/net/3c527.c 2007-10-02 17:31:08.000000000 +0000 +@@ -182,7 +182,7 @@ + + u16 rx_ring_tail; /* index to rx de-queue end */ + +- struct semaphore cmd_mutex; /* Serialises issuing of execute commands */ ++ struct compat_semaphore cmd_mutex; /* Serialises issuing of execute commands */ + struct completion execution_cmd; /* Card has completed an execute command */ + struct completion xceiver_cmd; /* Card has completed a tx or rx command */ + }; +diff -Nur custom-source-rt.orig/drivers/net/3c59x.c custom-source-rt/drivers/net/3c59x.c +--- custom-source-rt.orig/drivers/net/3c59x.c 2007-10-02 17:10:25.000000000 +0000 ++++ custom-source-rt/drivers/net/3c59x.c 2007-10-02 17:31:08.000000000 +0000 +@@ -792,9 +792,9 @@ + { + struct vortex_private *vp = netdev_priv(dev); + unsigned long flags; +- local_irq_save(flags); ++ local_irq_save_nort(flags); + (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + #endif + +@@ -1729,6 +1729,7 @@ + int next_tick = 60*HZ; + int ok = 0; + int media_status, old_window; ++ unsigned long flags; + + if (vortex_debug > 2) { + printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n", +@@ -1736,7 +1737,7 @@ + printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo); + } + +- disable_irq_lockdep(dev->irq); ++ spin_lock_irqsave(&vp->lock, flags); + old_window = ioread16(ioaddr + EL3_CMD) >> 13; + EL3WINDOW(4); + media_status = ioread16(ioaddr + Wn4_Media); +@@ -1759,9 +1760,7 @@ + case XCVR_MII: case XCVR_NWAY: + { + ok = 1; +- spin_lock_bh(&vp->lock); + vortex_check_media(dev, 0); +- spin_unlock_bh(&vp->lock); + } + break; + default: /* Other media types handled by Tx timeouts. */ +@@ -1817,7 +1816,7 @@ + dev->name, media_tbl[dev->if_port].name); + + EL3WINDOW(old_window); +- enable_irq_lockdep(dev->irq); ++ spin_unlock_irqrestore(&vp->lock, flags); + mod_timer(&vp->timer, RUN_AT(next_tick)); + if (vp->deferred) + iowrite16(FakeIntr, ioaddr + EL3_CMD); +@@ -1850,13 +1849,17 @@ + /* + * Block interrupts because vortex_interrupt does a bare spin_lock() + */ ++#ifndef CONFIG_PREEMPT_RT + unsigned long flags; + local_irq_save(flags); ++#endif + if (vp->full_bus_master_tx) + boomerang_interrupt(dev->irq, dev); + else + vortex_interrupt(dev->irq, dev); ++#ifndef CONFIG_PREEMPT_RT + local_irq_restore(flags); ++#endif + } + } + +diff -Nur custom-source-rt.orig/drivers/net/8139too.c custom-source-rt/drivers/net/8139too.c +--- custom-source-rt.orig/drivers/net/8139too.c 2007-08-21 04:00:24.000000000 +0000 ++++ custom-source-rt/drivers/net/8139too.c 2007-10-02 17:31:08.000000000 +0000 +@@ -2131,10 +2131,10 @@ + * Order is important since data can get interrupted + * again when we think we are done. + */ +- local_irq_save(flags); ++ local_irq_save_nort(flags); + RTL_W16_F(IntrMask, rtl8139_intr_mask); + __netif_rx_complete(dev); +- local_irq_restore(flags); ++ local_irq_restore_nort(flags); + } + spin_unlock(&tp->rx_lock); + +@@ -2214,7 +2214,11 @@ + */ + static void rtl8139_poll_controller(struct net_device *dev) + { +- disable_irq(dev->irq); ++ /* ++ * use _nosync() variant - might be used by netconsole ++ * from atomic contexts: ++ */ ++ disable_irq_nosync(dev->irq); + rtl8139_interrupt(dev->irq, dev); + enable_irq(dev->irq); + } +diff -Nur custom-source-rt.orig/drivers/net/hamradio/6pack.c custom-source-rt/drivers/net/hamradio/6pack.c +--- custom-source-rt.orig/drivers/net/hamradio/6pack.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/hamradio/6pack.c 2007-10-02 17:31:08.000000000 +0000 +@@ -123,7 +123,7 @@ + struct timer_list tx_t; + struct timer_list resync_t; + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + spinlock_t lock; + }; + +diff -Nur custom-source-rt.orig/drivers/net/hamradio/mkiss.c custom-source-rt/drivers/net/hamradio/mkiss.c +--- custom-source-rt.orig/drivers/net/hamradio/mkiss.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/hamradio/mkiss.c 2007-10-02 17:31:08.000000000 +0000 +@@ -84,7 +84,7 @@ + #define CRC_MODE_SMACK_TEST 4 + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + }; + + /*---------------------------------------------------------------------------*/ +diff -Nur custom-source-rt.orig/drivers/net/ibm_emac/ibm_emac_core.c custom-source-rt/drivers/net/ibm_emac/ibm_emac_core.c +--- custom-source-rt.orig/drivers/net/ibm_emac/ibm_emac_core.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/ibm_emac/ibm_emac_core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1059,6 +1059,8 @@ + ++dev->stats.tx_packets; + dev->stats.tx_bytes += len; + ++ spin_unlock(&dev->tx_lock); ++ + return 0; + } + +@@ -1072,6 +1074,7 @@ + u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY | + MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb); + ++ spin_lock(&dev->tx_lock); + slot = dev->tx_slot++; + if (dev->tx_slot == NUM_TX_BUFF) { + dev->tx_slot = 0; +@@ -1134,6 +1137,8 @@ + if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE)) + return emac_start_xmit(skb, ndev); + ++ spin_lock(&dev->tx_lock); ++ + len -= skb->data_len; + + /* Note, this is only an *estimation*, we can still run out of empty +@@ -1202,6 +1207,7 @@ + stop_queue: + netif_stop_queue(ndev); + DBG2("%d: stopped TX queue" NL, dev->def->index); ++ spin_unlock(&dev->tx_lock); + return 1; + } + #else +@@ -1241,6 +1247,7 @@ + DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt, + dev->ack_slot); + ++ spin_lock(&dev->tx_lock); + if (dev->tx_cnt) { + u16 ctrl; + int slot = dev->ack_slot, n = 0; +@@ -1250,6 +1257,7 @@ + struct sk_buff *skb = dev->tx_skb[slot]; + ++n; + ++ spin_unlock(&dev->tx_lock); + if (skb) { + dev_kfree_skb(skb); + dev->tx_skb[slot] = NULL; +@@ -1259,6 +1267,7 @@ + if (unlikely(EMAC_IS_BAD_TX(ctrl))) + emac_parse_tx_error(dev, ctrl); + ++ spin_lock(&dev->tx_lock); + if (--dev->tx_cnt) + goto again; + } +@@ -1271,6 +1280,7 @@ + DBG2("%d: tx %d pkts" NL, dev->def->index, n); + } + } ++ spin_unlock(&dev->tx_lock); + } + + static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot, +@@ -1963,6 +1973,7 @@ + dev->ldev = &ocpdev->dev; + dev->def = ocpdev->def; + SET_MODULE_OWNER(ndev); ++ spin_lock_init(&dev->tx_lock); + + /* Find MAL device we are connected to */ + maldev = +diff -Nur custom-source-rt.orig/drivers/net/ibm_emac/ibm_emac_core.h custom-source-rt/drivers/net/ibm_emac/ibm_emac_core.h +--- custom-source-rt.orig/drivers/net/ibm_emac/ibm_emac_core.h 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/ibm_emac/ibm_emac_core.h 2007-10-02 17:31:08.000000000 +0000 +@@ -193,6 +193,8 @@ + struct ibm_emac_error_stats estats; + struct net_device_stats nstats; + ++ spinlock_t tx_lock; ++ + struct device* ldev; + }; + +diff -Nur custom-source-rt.orig/drivers/net/loopback.c custom-source-rt/drivers/net/loopback.c +--- custom-source-rt.orig/drivers/net/loopback.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/loopback.c 2007-10-02 17:31:08.000000000 +0000 +@@ -154,12 +154,12 @@ + #endif + dev->last_rx = jiffies; + +- /* it's OK to use __get_cpu_var() because BHs are off */ +- lb_stats = &__get_cpu_var(pcpu_lstats); ++ lb_stats = &per_cpu(pcpu_lstats, get_cpu()); + lb_stats->bytes += skb->len; + lb_stats->packets++; ++ put_cpu(); + +- netif_rx(skb); ++ netif_rx_ni(skb); + + return 0; + } +diff -Nur custom-source-rt.orig/drivers/net/netconsole.c custom-source-rt/drivers/net/netconsole.c +--- custom-source-rt.orig/drivers/net/netconsole.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/netconsole.c 2007-10-02 17:31:08.000000000 +0000 +@@ -68,21 +68,16 @@ + static void write_msg(struct console *con, const char *msg, unsigned int len) + { + int frag, left; +- unsigned long flags; + + if (!np.dev) + return; + +- local_irq_save(flags); +- +- for(left = len; left; ) { ++ for (left = len; left; ) { + frag = min(left, MAX_PRINT_CHUNK); + netpoll_send_udp(&np, msg, frag); + msg += frag; + left -= frag; + } +- +- local_irq_restore(flags); + } + + static struct console netconsole = { +diff -Nur custom-source-rt.orig/drivers/net/plip.c custom-source-rt/drivers/net/plip.c +--- custom-source-rt.orig/drivers/net/plip.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/plip.c 2007-10-02 17:31:08.000000000 +0000 +@@ -228,7 +228,10 @@ + struct hh_cache *hh); + spinlock_t lock; + atomic_t kill_timer; +- struct semaphore killed_timer_sem; ++ /* ++ * PREEMPT_RT: this isnt a mutex, it should be struct completion. ++ */ ++ struct compat_semaphore killed_timer_sem; + }; + + static inline void enable_parport_interrupts (struct net_device *dev) +diff -Nur custom-source-rt.orig/drivers/net/ppp_async.c custom-source-rt/drivers/net/ppp_async.c +--- custom-source-rt.orig/drivers/net/ppp_async.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/ppp_async.c 2007-10-02 17:31:08.000000000 +0000 +@@ -67,7 +67,7 @@ + struct tasklet_struct tsk; + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + struct ppp_channel chan; /* interface to generic ppp layer */ + unsigned char obuf[OBUFSIZE]; + }; +diff -Nur custom-source-rt.orig/drivers/net/ppp_synctty.c custom-source-rt/drivers/net/ppp_synctty.c +--- custom-source-rt.orig/drivers/net/ppp_synctty.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/ppp_synctty.c 2007-10-02 17:31:08.000000000 +0000 +@@ -70,7 +70,7 @@ + struct tasklet_struct tsk; + + atomic_t refcnt; +- struct semaphore dead_sem; ++ struct compat_semaphore dead_sem; + struct ppp_channel chan; /* interface to generic ppp layer */ + }; + +diff -Nur custom-source-rt.orig/drivers/net/sungem.c custom-source-rt/drivers/net/sungem.c +--- custom-source-rt.orig/drivers/net/sungem.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/sungem.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1034,10 +1034,8 @@ + (csum_stuff_off << 21)); + } + +- local_irq_save(flags); +- if (!spin_trylock(&gp->tx_lock)) { ++ if (!spin_trylock_irqsave(&gp->tx_lock, flags)) { + /* Tell upper layer to requeue */ +- local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } + /* We raced with gem_do_stop() */ +diff -Nur custom-source-rt.orig/drivers/net/tulip/tulip_core.c custom-source-rt/drivers/net/tulip/tulip_core.c +--- custom-source-rt.orig/drivers/net/tulip/tulip_core.c 2007-08-21 04:00:25.000000000 +0000 ++++ custom-source-rt/drivers/net/tulip/tulip_core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1812,6 +1812,7 @@ + pci_iounmap(pdev, tp->base_addr); + free_netdev (dev); + pci_release_regions (pdev); ++ pci_disable_device (pdev); + pci_set_drvdata (pdev, NULL); + + /* pci_power_off (pdev, -1); */ +diff -Nur custom-source-rt.orig/drivers/net/usb/usbnet.c custom-source-rt/drivers/net/usb/usbnet.c +--- custom-source-rt.orig/drivers/net/usb/usbnet.c 2007-08-21 04:00:26.000000000 +0000 ++++ custom-source-rt/drivers/net/usb/usbnet.c 2007-10-02 17:31:08.000000000 +0000 +@@ -896,6 +896,8 @@ + + urb->dev = NULL; + entry->state = tx_done; ++ spin_lock_rt(&dev->txq.lock); ++ spin_unlock_rt(&dev->txq.lock); + defer_bh(dev, skb, &dev->txq); + } + +diff -Nur custom-source-rt.orig/drivers/oprofile/oprofilefs.c custom-source-rt/drivers/oprofile/oprofilefs.c +--- custom-source-rt.orig/drivers/oprofile/oprofilefs.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/oprofile/oprofilefs.c 2007-10-02 17:31:08.000000000 +0000 +@@ -21,7 +21,7 @@ + + #define OPROFILEFS_MAGIC 0x6f70726f + +-DEFINE_SPINLOCK(oprofilefs_lock); ++DEFINE_RAW_SPINLOCK(oprofilefs_lock); + + static struct inode * oprofilefs_get_inode(struct super_block * sb, int mode) + { +diff -Nur custom-source-rt.orig/drivers/pci/access.c custom-source-rt/drivers/pci/access.c +--- custom-source-rt.orig/drivers/pci/access.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/access.c 2007-10-02 17:31:08.000000000 +0000 +@@ -11,7 +11,7 @@ + * configuration space. + */ + +-static DEFINE_SPINLOCK(pci_lock); ++static DEFINE_RAW_SPINLOCK(pci_lock); + + /* + * Wrappers for all PCI configuration access functions. They just check +diff -Nur custom-source-rt.orig/drivers/pci/hotplug/cpci_hotplug_core.c custom-source-rt/drivers/pci/hotplug/cpci_hotplug_core.c +--- custom-source-rt.orig/drivers/pci/hotplug/cpci_hotplug_core.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/hotplug/cpci_hotplug_core.c 2007-10-02 17:31:08.000000000 +0000 +@@ -59,8 +59,8 @@ + static atomic_t extracting; + int cpci_debug; + static struct cpci_hp_controller *controller; +-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +-static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ ++static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ ++static struct compat_semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ + static int thread_finished = 1; + + static int enable_slot(struct hotplug_slot *slot); +@@ -521,9 +521,9 @@ + { + int rc; + +- lock_kernel(); ++// lock_kernel(); + daemonize("cpci_hp_eventd"); +- unlock_kernel(); ++// unlock_kernel(); + + dbg("%s - event thread started", __FUNCTION__); + while (1) { +@@ -562,9 +562,9 @@ + { + int rc; + +- lock_kernel(); ++// lock_kernel(); + daemonize("cpci_hp_polld"); +- unlock_kernel(); ++// unlock_kernel(); + + while (1) { + if (thread_finished || signal_pending(current)) +diff -Nur custom-source-rt.orig/drivers/pci/hotplug/cpqphp_ctrl.c custom-source-rt/drivers/pci/hotplug/cpqphp_ctrl.c +--- custom-source-rt.orig/drivers/pci/hotplug/cpqphp_ctrl.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/hotplug/cpqphp_ctrl.c 2007-10-02 17:31:08.000000000 +0000 +@@ -45,8 +45,8 @@ + u8 behind_bridge, struct resource_lists *resources); + static void interrupt_event_handler(struct controller *ctrl); + +-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +-static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ ++static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */ ++static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */ + static int event_finished; + static unsigned long pushbutton_pending; /* = 0 */ + +@@ -1746,10 +1746,10 @@ + static int event_thread(void* data) + { + struct controller *ctrl; +- lock_kernel(); ++// lock_kernel(); + daemonize("phpd_event"); + +- unlock_kernel(); ++// unlock_kernel(); + + while (1) { + dbg("!!!!event_thread sleeping\n"); +diff -Nur custom-source-rt.orig/drivers/pci/hotplug/ibmphp_hpc.c custom-source-rt/drivers/pci/hotplug/ibmphp_hpc.c +--- custom-source-rt.orig/drivers/pci/hotplug/ibmphp_hpc.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/hotplug/ibmphp_hpc.c 2007-10-02 17:31:08.000000000 +0000 +@@ -106,7 +106,7 @@ + static struct mutex sem_hpcaccess; // lock access to HPC + static struct semaphore semOperations; // lock all operations and + // access to data structures +-static struct semaphore sem_exit; // make sure polling thread goes away ++static struct compat_semaphore sem_exit; // make sure polling thread goes away + //---------------------------------------------------------------------------- + // local function prototypes + //---------------------------------------------------------------------------- +diff -Nur custom-source-rt.orig/drivers/pci/msi.c custom-source-rt/drivers/pci/msi.c +--- custom-source-rt.orig/drivers/pci/msi.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/msi.c 2007-10-02 17:31:08.000000000 +0000 +@@ -235,6 +235,10 @@ + return; + + entry = get_irq_msi(dev->irq); ++ if (!entry) { ++ WARN_ON(1); ++ return; ++ } + pos = entry->msi_attrib.pos; + + pci_intx(dev, 0); /* disable intx */ +diff -Nur custom-source-rt.orig/drivers/pci/pcie/aer/aerdrv.c custom-source-rt/drivers/pci/pcie/aer/aerdrv.c +--- custom-source-rt.orig/drivers/pci/pcie/aer/aerdrv.c 2007-08-21 04:00:27.000000000 +0000 ++++ custom-source-rt/drivers/pci/pcie/aer/aerdrv.c 2007-10-02 17:31:08.000000000 +0000 +@@ -157,7 +157,7 @@ + * Initialize Root lock access, e_lock, to Root Error Status Reg, + * Root Error ID Reg, and Root error producer/consumer index. + */ +- rpc->e_lock = SPIN_LOCK_UNLOCKED; ++ spin_lock_init(&rpc->e_lock); + + rpc->rpd = dev; + INIT_WORK(&rpc->dpc_handler, aer_isr); +diff -Nur custom-source-rt.orig/drivers/scsi/aacraid/aacraid.h custom-source-rt/drivers/scsi/aacraid/aacraid.h +--- custom-source-rt.orig/drivers/scsi/aacraid/aacraid.h 2007-08-21 04:00:28.000000000 +0000 ++++ custom-source-rt/drivers/scsi/aacraid/aacraid.h 2007-10-02 17:31:08.000000000 +0000 +@@ -715,7 +715,7 @@ + u32 unique; // unique value representing this context + ulong jiffies; // used for cleanup - dmb changed to ulong + struct list_head next; // used to link context's into a linked list +- struct semaphore wait_sem; // this is used to wait for the next fib to arrive. ++ struct compat_semaphore wait_sem; // this is used to wait for the next fib to arrive. + int wait; // Set to true when thread is in WaitForSingleObject + unsigned long count; // total number of FIBs on FibList + struct list_head fib_list; // this holds fibs and their attachd hw_fibs +@@ -785,7 +785,7 @@ + * This is the event the sendfib routine will wait on if the + * caller did not pass one and this is synch io. + */ +- struct semaphore event_wait; ++ struct compat_semaphore event_wait; + spinlock_t event_lock; + + u32 done; /* gets set to 1 when fib is complete */ +diff -Nur custom-source-rt.orig/drivers/scsi/qla2xxx/qla_def.h custom-source-rt/drivers/scsi/qla2xxx/qla_def.h +--- custom-source-rt.orig/drivers/scsi/qla2xxx/qla_def.h 2007-08-21 04:00:28.000000000 +0000 ++++ custom-source-rt/drivers/scsi/qla2xxx/qla_def.h 2007-10-02 17:31:08.000000000 +0000 +@@ -2344,7 +2344,7 @@ + #define MBX_UPDATE_FLASH_ACTIVE 3 + + struct semaphore mbx_cmd_sem; /* Serialialize mbx access */ +- struct semaphore mbx_intr_sem; /* Used for completion notification */ ++ struct compat_semaphore mbx_intr_sem; /* Used for completion notification */ + + uint32_t mbx_flags; + #define MBX_IN_PROGRESS BIT_0 +diff -Nur custom-source-rt.orig/drivers/serial/8250.c custom-source-rt/drivers/serial/8250.c +--- custom-source-rt.orig/drivers/serial/8250.c 2007-08-21 04:00:28.000000000 +0000 ++++ custom-source-rt/drivers/serial/8250.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1451,7 +1451,10 @@ + { + struct irq_info *i = dev_id; + struct list_head *l, *end = NULL; +- int pass_counter = 0, handled = 0; ++#ifndef CONFIG_PREEMPT_RT ++ int pass_counter = 0; ++#endif ++ int handled = 0; + + DEBUG_INTR("serial8250_interrupt(%d)...", irq); + +@@ -1489,12 +1492,18 @@ + + l = l->next; + ++ /* ++ * On preempt-rt we can be preempted and run in our ++ * own thread. ++ */ ++#ifndef CONFIG_PREEMPT_RT + if (l == i->head && pass_counter++ > PASS_LIMIT) { + /* If we hit this, we're dead. */ + printk(KERN_ERR "serial8250: too much work for " + "irq%d\n", irq); + break; + } ++#endif + } while (l != end); + + spin_unlock(&i->lock); +@@ -2456,14 +2465,10 @@ + + touch_nmi_watchdog(); + +- local_irq_save(flags); +- if (up->port.sysrq) { +- /* serial8250_handle_port() already took the lock */ +- locked = 0; +- } else if (oops_in_progress) { +- locked = spin_trylock(&up->port.lock); +- } else +- spin_lock(&up->port.lock); ++ if (up->port.sysrq || oops_in_progress) ++ locked = spin_trylock_irqsave(&up->port.lock, flags); ++ else ++ spin_lock_irqsave(&up->port.lock, flags); + + /* + * First save the IER then disable the interrupts +@@ -2485,8 +2490,7 @@ + serial_out(up, UART_IER, ier); + + if (locked) +- spin_unlock(&up->port.lock); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(&up->port.lock, flags); + } + + static int __init serial8250_console_setup(struct console *co, char *options) +diff -Nur custom-source-rt.orig/drivers/usb/core/devio.c custom-source-rt/drivers/usb/core/devio.c +--- custom-source-rt.orig/drivers/usb/core/devio.c 2007-08-21 04:00:28.000000000 +0000 ++++ custom-source-rt/drivers/usb/core/devio.c 2007-10-02 17:31:08.000000000 +0000 +@@ -308,10 +308,11 @@ + struct async *as = urb->context; + struct dev_state *ps = as->ps; + struct siginfo sinfo; ++ unsigned long flags; + +- spin_lock(&ps->lock); +- list_move_tail(&as->asynclist, &ps->async_completed); +- spin_unlock(&ps->lock); ++ spin_lock_irqsave(&ps->lock, flags); ++ list_move_tail(&as->asynclist, &ps->async_completed); ++ spin_unlock_irqrestore(&ps->lock, flags); + if (as->signr) { + sinfo.si_signo = as->signr; + sinfo.si_errno = as->urb->status; +diff -Nur custom-source-rt.orig/drivers/usb/core/hcd.c custom-source-rt/drivers/usb/core/hcd.c +--- custom-source-rt.orig/drivers/usb/core/hcd.c 2007-08-21 04:00:29.000000000 +0000 ++++ custom-source-rt/drivers/usb/core/hcd.c 2007-10-02 17:31:08.000000000 +0000 +@@ -518,13 +518,11 @@ + } + + /* any errors get returned through the urb completion */ +- local_irq_save (flags); +- spin_lock (&urb->lock); ++ spin_lock_irqsave(&urb->lock, flags); + if (urb->status == -EINPROGRESS) + urb->status = status; +- spin_unlock (&urb->lock); ++ spin_unlock_irqrestore(&urb->lock, flags); + usb_hcd_giveback_urb (hcd, urb); +- local_irq_restore (flags); + return 0; + } + +@@ -554,8 +552,7 @@ + if (length > 0) { + + /* try to complete the status urb */ +- local_irq_save (flags); +- spin_lock(&hcd_root_hub_lock); ++ spin_lock_irqsave(&hcd_root_hub_lock, flags); + urb = hcd->status_urb; + if (urb) { + spin_lock(&urb->lock); +@@ -571,14 +568,13 @@ + spin_unlock(&urb->lock); + } else + length = 0; +- spin_unlock(&hcd_root_hub_lock); ++ spin_unlock_irqrestore(&hcd_root_hub_lock, flags); + + /* local irqs are always blocked in completions */ + if (length > 0) + usb_hcd_giveback_urb (hcd, urb); + else + hcd->poll_pending = 1; +- local_irq_restore (flags); + } + + /* The USB 2.0 spec says 256 ms. This is close enough and won't +@@ -650,17 +646,15 @@ + } else { /* Status URB */ + if (!hcd->uses_new_polling) + del_timer (&hcd->rh_timer); +- local_irq_save (flags); +- spin_lock (&hcd_root_hub_lock); ++ spin_lock_irqsave(&hcd_root_hub_lock, flags); + if (urb == hcd->status_urb) { + hcd->status_urb = NULL; + urb->hcpriv = NULL; + } else + urb = NULL; /* wasn't fully queued */ +- spin_unlock (&hcd_root_hub_lock); ++ spin_unlock_irqrestore(&hcd_root_hub_lock, flags); + if (urb) + usb_hcd_giveback_urb (hcd, urb); +- local_irq_restore (flags); + } + + return 0; +@@ -1175,11 +1169,10 @@ + struct urb *urb; + + hcd = bus_to_hcd(udev->bus); +- local_irq_disable (); + + /* ep is already gone from udev->ep_{in,out}[]; no more submits */ + rescan: +- spin_lock (&hcd_data_lock); ++ spin_lock_irq(&hcd_data_lock); + list_for_each_entry (urb, &ep->urb_list, urb_list) { + int tmp; + +@@ -1187,13 +1180,13 @@ + if (urb->status != -EINPROGRESS) + continue; + usb_get_urb (urb); +- spin_unlock (&hcd_data_lock); ++ spin_unlock_irq(&hcd_data_lock); + +- spin_lock (&urb->lock); ++ spin_lock_irq(&urb->lock); + tmp = urb->status; + if (tmp == -EINPROGRESS) + urb->status = -ESHUTDOWN; +- spin_unlock (&urb->lock); ++ spin_unlock_irq(&urb->lock); + + /* kick hcd unless it's already returning this */ + if (tmp == -EINPROGRESS) { +@@ -1216,8 +1209,7 @@ + /* list contents may have changed */ + goto rescan; + } +- spin_unlock (&hcd_data_lock); +- local_irq_enable (); ++ spin_unlock_irq(&hcd_data_lock); + + /* synchronize with the hardware, so old configuration state + * clears out immediately (and will be freed). +diff -Nur custom-source-rt.orig/drivers/usb/core/message.c custom-source-rt/drivers/usb/core/message.c +--- custom-source-rt.orig/drivers/usb/core/message.c 2007-10-02 17:10:26.000000000 +0000 ++++ custom-source-rt/drivers/usb/core/message.c 2007-10-02 17:31:08.000000000 +0000 +@@ -250,8 +250,9 @@ + static void sg_complete (struct urb *urb) + { + struct usb_sg_request *io = urb->context; ++ unsigned long flags; + +- spin_lock (&io->lock); ++ spin_lock_irqsave (&io->lock, flags); + + /* In 2.5 we require hcds' endpoint queues not to progress after fault + * reports, until the completion callback (this!) returns. That lets +@@ -285,7 +286,7 @@ + * unlink pending urbs so they won't rx/tx bad data. + * careful: unlink can sometimes be synchronous... + */ +- spin_unlock (&io->lock); ++ spin_unlock_irqrestore (&io->lock, flags); + for (i = 0, found = 0; i < io->entries; i++) { + if (!io->urbs [i] || !io->urbs [i]->dev) + continue; +@@ -300,7 +301,7 @@ + } else if (urb == io->urbs [i]) + found = 1; + } +- spin_lock (&io->lock); ++ spin_lock_irqsave (&io->lock, flags); + } + urb->dev = NULL; + +@@ -310,7 +311,7 @@ + if (!io->count) + complete (&io->complete); + +- spin_unlock (&io->lock); ++ spin_unlock_irqrestore (&io->lock, flags); + } + + +@@ -586,7 +587,7 @@ + dev_warn (&io->dev->dev, "%s, unlink --> %d\n", + __FUNCTION__, retval); + } +- spin_lock (&io->lock); ++ spin_lock_irqsave (&io->lock, flags); + } + spin_unlock_irqrestore (&io->lock, flags); + } +diff -Nur custom-source-rt.orig/drivers/usb/storage/usb.h custom-source-rt/drivers/usb/storage/usb.h +--- custom-source-rt.orig/drivers/usb/storage/usb.h 2007-08-21 04:00:29.000000000 +0000 ++++ custom-source-rt/drivers/usb/storage/usb.h 2007-10-02 17:31:08.000000000 +0000 +@@ -146,7 +146,7 @@ + dma_addr_t iobuf_dma; + + /* mutual exclusion and synchronization structures */ +- struct semaphore sema; /* to sleep thread on */ ++ struct compat_semaphore sema; /* to sleep thread on */ + struct completion notify; /* thread begin/end */ + wait_queue_head_t delay_wait; /* wait during scan, reset */ + +diff -Nur custom-source-rt.orig/drivers/video/console/fbcon.c custom-source-rt/drivers/video/console/fbcon.c +--- custom-source-rt.orig/drivers/video/console/fbcon.c 2007-08-21 04:00:29.000000000 +0000 ++++ custom-source-rt/drivers/video/console/fbcon.c 2007-10-02 17:31:08.000000000 +0000 +@@ -1287,7 +1287,6 @@ + { + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; +- + struct display *p = &fb_display[vc->vc_num]; + u_int y_break; + +@@ -1316,10 +1315,11 @@ + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + +- if (!fbcon_is_inactive(vc, info)) ++ if (!fbcon_is_inactive(vc, info)) { + ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, + get_color(vc, info, scr_readw(s), 1), + get_color(vc, info, scr_readw(s), 0)); ++ } + } + + static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) +@@ -3173,6 +3173,7 @@ + .con_screen_pos = fbcon_screen_pos, + .con_getxy = fbcon_getxy, + .con_resize = fbcon_resize, ++ .con_preemptible = 1, + }; + + static struct notifier_block fbcon_event_notifier = { +diff -Nur custom-source-rt.orig/drivers/video/console/vgacon.c custom-source-rt/drivers/video/console/vgacon.c +--- custom-source-rt.orig/drivers/video/console/vgacon.c 2007-08-21 04:00:29.000000000 +0000 ++++ custom-source-rt/drivers/video/console/vgacon.c 2007-10-02 17:31:08.000000000 +0000 +@@ -51,7 +51,7 @@ + #include